BackgroundDownloader Макс Параллелизм

Есть ли способ установить максимальное количество одновременных загрузок с BackgroundDownloader?

Примерно этим я и занимаюсь.

var downloader = new BackgroundDownloader();
foreach( var uri in uriList )
{
    var download = downloader.CreateDownload( uri, storageFile );
    download.StartAsync().AsTask( cancellationTokenSource.Token, progress );
}

Я хотел бы иметь возможность установить максимальный параллелизм загрузки, скажем, 4. Это встроено, или мне нужно управлять этим самостоятельно?

Если мне нужно управлять этим самостоятельно, каков рекомендуемый способ? Я думал просто сделать Parallel.ForEach и установить там максимальную сумму, но я не знаю, хорошее ли это решение.


person Josh Close    schedule 28.03.2014    source источник
comment
Интересно, не могли бы вы сделать что-то вроде того, чтобы поместить все Task в 3 корзины: Queue, Downloading, Done. Используя Task.WhenAny в списке Downloading, удалите эту задачу и поместите ее в список «Готово», затем dequeue и начните новую, добавив ее в Downloading.   -  person Nate Diamond    schedule 29.03.2014
comment
Не могли бы вы собрать рабочий пример и опубликовать его в качестве ответа? Я пробовал несколько разных способов здесь, и ничего не работает совершенно правильно. Выполнение этого как Parallel.ForEach работает, но тогда обратный вызов находится в другом потоке, и у меня возникают проблемы с запуском вещей в CoreDispatcher. Я бы предпочел делать все, используя async/await, если смогу; тем более, что операции загрузки уже асинхронны.   -  person Josh Close    schedule 29.03.2014


Ответы (1)


Это то, что я в итоге сделал. Это не полное, но это суть.

private void StartDownloadsAsync()
{
    var downloadQueue = new Queue<DownloadOperation>();
    // Create all the download operations and add them to the queue.
    await CreateDownloadsAsync();
    var maxConcurrentDownloads = 4;
    var loopAmount = Math.Min( maxConcurrentDownloads, downloadQueue.Count );
    for( var i = 0; i < loopAmount; i++ )
    {
        DownloadAsync();
    }
}

private void DownloadAsync()
{
    var download = downloadQueue.Dequeue();

    HandleDownloadAsync( download ).ContinueWith( task => DownloadComplete( download ) );
}

private void DownloadComplete( DownloadOperation download )
{
    // Update progress counter here.

    if( downloadQueue.Count > 0 )
    {
        DownloadAsync();
    }
    else
    {
        // Downloads are done. Do something.
    }
}

private async Task HandleDownloadAsync( DownloadOperation download, bool isActive = false )
{
    if( !isActive )
    {
        await download.StartAsync().AsTask( cancellationTokenSource.Token );
    }
    {
        await download.AttachAsync().AsTask( cancellationTokenSource.Token );
    }
}
person Josh Close    schedule 06.04.2014