@@ -34,7 +34,7 @@ public class MultiThreadDownloader : Downloader
34
34
private long taskId = 0 ; //本地下载任务的 ID
35
35
private long runningThreadCount = 0 ; //正在运行的线程数
36
36
private object locker = new object ( ) ;
37
- private object sliceFileLocker = new object ( ) ;
37
+ private Cache cache = new Cache ( ) ;
38
38
39
39
public MultiThreadDownloader ( BaiduPCS pcs , PcsFileInfo from , string to ,
40
40
string workfolder , int threadCount , int minSliceSize = MIN_SLICE_SIZE )
@@ -71,6 +71,11 @@ public override void Download()
71
71
CreateDirectory ( to ) ; //创建目录
72
72
CreateLocalFile ( ) ; // 如果需要则创建本地文件
73
73
bigfile = new BigFileHelper ( to , from . size ) ; //映射文件到内存
74
+ lock ( cache )
75
+ {
76
+ cache . Reset ( ) ;
77
+ cache . FileHelper = bigfile ;
78
+ }
74
79
foreach ( Slice slice in SliceList )
75
80
{
76
81
if ( slice . status != SliceStatus . Successed )
@@ -201,6 +206,8 @@ private void downloadTask(object objTID)
201
206
string errmsg ;
202
207
pcs = this . pcs . clone ( ) ;
203
208
pcs . Write += onWrite ;
209
+ Random rnd = new Random ( Environment . TickCount ) ;
210
+ Thread . Sleep ( rnd . Next ( 1 , 10 ) ) ;
204
211
while ( tid == Interlocked . Read ( ref taskId ) )
205
212
{
206
213
slice = popSlice ( ) ;
@@ -216,6 +223,16 @@ private void downloadTask(object objTID)
216
223
rc = pcs . download ( from . path , 0 ,
217
224
slice . start + slice . doneSize ,
218
225
slice . totalSize - slice . doneSize ) ;
226
+ lock ( cache )
227
+ {
228
+ if ( cache . TotalSize > 0 )
229
+ {
230
+ if ( ! cache . Flush ( ) )
231
+ throw new Exception ( "Failed to flush cache." ) ;
232
+ cache . Reset ( ) ;
233
+ SliceHelper . SaveSliceList ( SliceFileName , SliceList ) ; // 保存最新的分片数据
234
+ }
235
+ }
219
236
if ( rc == PcsRes . PCS_OK || slice . status == SliceStatus . Successed )
220
237
slice . status = SliceStatus . Successed ;
221
238
else if ( slice . status == SliceStatus . Cancelled )
@@ -288,13 +305,10 @@ private uint onWrite(BaiduPCS sender, byte[] data, uint contentlength, object us
288
305
size = slice . totalSize - slice . doneSize ;
289
306
if ( size > 0 )
290
307
{
291
- try
292
- {
293
- bigfile . Update ( slice . start + slice . doneSize , data , 0 , ( int ) size ) ;
294
- }
295
- catch ( Exception ex )
308
+ lock ( cache )
296
309
{
297
- throw ;
310
+ if ( ! cache . Add ( slice . start + slice . doneSize , data , ( int ) size ) )
311
+ throw new Exception ( "Failed to add to disk cache." ) ;
298
312
}
299
313
}
300
314
slice . doneSize += size ;
@@ -304,7 +318,16 @@ private uint onWrite(BaiduPCS sender, byte[] data, uint contentlength, object us
304
318
slice . status = SliceStatus . Successed ;
305
319
size = 0 ;
306
320
}
307
- lock ( sliceFileLocker ) SliceHelper . SaveSliceList ( SliceFileName , SliceList ) ; // 保存最新的分片数据
321
+ lock ( cache )
322
+ {
323
+ if ( cache . TotalSize >= AppSettings . MaxCacheSize * 1024 )
324
+ {
325
+ if ( ! cache . Flush ( ) )
326
+ throw new Exception ( "Failed to flush cache." ) ;
327
+ cache . Reset ( ) ;
328
+ SliceHelper . SaveSliceList ( SliceFileName , SliceList ) ; // 保存最新的分片数据
329
+ }
330
+ }
308
331
long downloadedSize = 0 ;
309
332
lock ( locker ) downloadedSize = DoneSize ;
310
333
ProgressEventArgs args = new ProgressEventArgs ( downloadedSize , from . size ) ;
0 commit comments