2012-12-19 13 views
9

Arka Plan Aktarımı API'sini kullanırken, uygulama sona erdikten sonra yeniden başlatmayı denemek için mevcut veri aktarımları üzerinden yinelemeliyiz (örn. Sistem kapatma). Gelişim bilgisi almak ve veri aktarımlarını iptal edebilmek için AttachAsync kullanılarak iliştirilmelidir.DownloadOperation'ın AttachAsync'ini hemen nasıl çözmezsiniz?

Sorunum, AttachAsync'in yalnızca veri aktarımı bittiğinde geri dönmesidir. Bazı senaryolarda bu mantıklı. Ancak birden fazla veri aktarımı yapılırken, listedeki bir sonraki aktarım şu anda eklenene kadar başlatılmayacaktır. . Bu sorunun çözümü My AttachAsync() AsTask() klasik bir şekilde döner Görev işlemek için oldu (kullanmak bekliyor ama continuations):

IReadOnlyList<DownloadOperation> currentDownloads = 
    await BackgroundDownloader.GetCurrentDownloadsAsync(); 
foreach (var downloadOperation in currentDownloads) 
{ 
    Task task = downloadOperation.AttachAsync().AsTask(); 

    DownloadOperation operation = downloadOperation; 
    task.ContinueWith(_ => 
    { 
     // Handle success 
     ... 
    }, CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, 
    TaskScheduler.FromCurrentSynchronizationContext()); 

    task.ContinueWith(_ => 
    { 
     // Handle cancellation 
     ... 
    }, CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, 
    TaskScheduler.FromCurrentSynchronizationContext()); 

    task.ContinueWith(t => 
    { 
    // Handle errors 
     ... 

    }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, 
    TaskScheduler.FromCurrentSynchronizationContext()); 
} 
Bu tür fiili kodunda (işleri

ben eklemek bir ListBox'a indirilir). Döngü, tüm indirmeler boyunca yinelenir ve StartAsync'i yürütür. Ancak indirme işlemleri aynı anda tamamen başlatılmamış. Bir seferde sadece bir tanesi çalışır ve sadece bir sonraki devam ederse devam eder.

Bu sorun için herhangi bir çözüm var mı?

cevap

3

Task'un tüm noktası, paralel işlemler seçeneğine sahip olmanıza izin vermektir. Eğer await numaralı telefonu kullanırsanız, o zaman işlemlerin serileştirilmesi için kodlara söylüyorsunuz; Eğer beklemezsen, kodun paralelleşmesini söylüyorsun.

Yapabilecekleriniz, her indirme görevini, kodun paralelleştirileceğini bildiren bir listeye eklemektir. Daha sonra görevlerin birer birer bitmesini bekleyebilirsiniz.

böyle bir şey nasıl

IReadOnlyList<DownloadOperation> currentDownloads = 
    await BackgroundDownloader.GetCurrentDownloadsAsync(); 
if (currentDownloads.Count > 0) 
{ 
    List<Task<DownloadOperation>> tasks = new List<Task<DownloadOperation>>(); 
    foreach (DownloadOperation downloadOperation in currentDownloads) 
    { 
     // Attach progress and completion handlers without waiting for completion 
     tasks.Add(downloadOperation.AttachAsync().AsTask()); 
    } 

    while (tasks.Count > 0) 
    { 
     // wait for ANY download task to finish 
     Task<DownloadOperation> task = await Task.WhenAny<DownloadOperation>(tasks); 
     tasks.Remove(task); 

     // process the completed task... 
     if (task.IsCanceled) 
     { 
      // handle cancel 
     } 
     else if (task.IsFaulted) 
     { 
      // handle exception 
     } 
     else if (task.IsCompleted) 
     { 
      DownloadOperation dl = task.Result; 
      // handle completion (e.g. add to your listbox) 
     } 
     else 
     { 
      // should never get here.... 
     } 
    } 
} 
+0

teşekkür ederiz, acaba sorusu Görevler ilgili değildi. Yükleme tamamlanana kadar AttachAsync'in geri dönmemesi ile ilgili sorun oldu. Benim çözümüm işe yarıyor. Sorumluluğumun gerçek cevabı, AttachAsync'in bu davranışının bir indirme işleminin ne zaman tamamlandığını tespit etmemize izin vermesidir. –

+0

@ Jürgen Bayer - Belki de meselenin nerede olduğunu anlamıyorum. Kodumu hata ayıklayıcısında çalıştırdığımda, 'AttachAsync' komutunu veren satır hemen döner. Bekleyen tek yer, beklemesi gereken "while" döngüsüdür - indirme işlemlerinin tamamlanma olayını ele alır. –

+0

Bu AttachAsync hemen döndürme ile beklemediğinden, ancak bekletme oluşturmak için döndürülen görevi kullanın çünkü hemen. Sorun şuydu: Birden fazla yükleme etkinken bir Uygulama sonlandırıldıysa, her bir AttachAsync için beklemeden uygulama yeniden başlatıldığında tüm indirmelerin ekleneceği bir çözüm arıyordum. Umudum, daha sonra indirmelerin, StartAsync'i kullanarak birden çok kez başlatıldıklarında (StartAsync'i çalıştıran yöntem birden çok kez çalıştırıldığında) paralel olarak çalışacaktı. Ama bu gerçekleşmez. AtttachAsync ile bir seferde sadece bir indirme işlemi gerçekleştirir. –

İlgili konular