Я играл с примерами для параллельного программирования с .NET Framework, расположенными здесь и узнал кучу действительно замечательных вещей.
В частности, я пытаюсь создать простую программу, которая извлекает список RSS-каналов, а затем анализирует конкретную информацию.
В решении AsyncDownload_CSharp
представлен ряд примеров асинхронной загрузки. У меня есть довольно приличное понимание следующего фрагмента кода:
// Concurrent async requests
Task.Factory.ContinueWhenAll(new []
{
Download("http://blogs.msdn.com/pfxteam"),
Download("http://blogs.msdn.com/nativeconcurrency"),
Download("http://exampleexampleexample.com"), // will fail
Download("http://msdn.com/concurrency"),
Download("http://bing.com")
}, ConcurrentTasksCompleted).Wait();
В приведенном выше коде есть список жесткого кода задач, и я пытался выяснить, как мне динамически генерировать этот список задач, где я присваиваю значение url во время выполнения либо через цикл foreach
, либо через какой-либо другая повторяющаяся петля.
Код, который я придумал для динамического построения списка задач и передачи его в Task.Factory.ContinueWhenAll looks
, выглядит следующим образом:
private void btnFeeds_Click(object sender, EventArgs e)
{
string[] urls = new[] { "http://blogs.msdn.com/pfxteam",
"http://msdn.com/concurrency", "http://bing.com" };
List<Task<string>> tasks = new List<Task<string>>();
foreach (string url in urls)
{
tasks.Add(Download(url));
}
Task.Factory.ContinueWhenAll(tasks, ConcurrentTasksCompleted).Wait();
}
К сожалению, когда я прохожу через отладчик, я вижу не только создание списка задач, но и то, как они добавляются в список задач, но я также вижу, как они выполняются перед передачей в Task.Factory.ContinueWhenAll
.
Я думаю, мне нужно использовать лямбда-выражение вместо этого цикла foreach
, чтобы передать каждое из них в Task.Factory.ContinueWhenAll
. К сожалению, мне трудно понять, как применяется URL-адрес задачи с использованием лямбда-выражения.
Я не уверен, возможно ли то, что я пытаюсь сделать, поэтому любые предложения, указатели или помощь будут очень признательны.
1 ответ
Потому что вы используете метод DownLoad(url)
для создания объекта задачи. в методе DownLoad(url)
задача фактически уже была запущена, вы можете проверить код в ParallelExtensionsExtras/Extensions/EAP/WebClientExtensions.cs
/// <summary>Downloads the resource with the specified URI as a byte array, asynchronously.</summary>
/// <param name="webClient">The WebClient.</param>
/// <param name="address">The URI from which to download data.</param>
/// <returns>A Task that contains the downloaded data.</returns>
public static Task<byte[]> DownloadDataTask(this WebClient webClient, string address)
{
return DownloadDataTask(webClient, new Uri(address));
}
/// <summary>Downloads the resource with the specified URI as a byte array, asynchronously.</summary>
/// <param name="webClient">The WebClient.</param>
/// <param name="address">The URI from which to download data.</param>
/// <returns>A Task that contains the downloaded data.</returns>
public static Task<byte[]> DownloadDataTask(this WebClient webClient, Uri address)
{
// Create the task to be returned
var tcs = new TaskCompletionSource<byte[]>(address);
// Setup the callback event handler
DownloadDataCompletedEventHandler handler = null;
handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.DownloadDataCompleted -= handler);
webClient.DownloadDataCompleted += handler;
// Start the async work
try
{
webClient.DownloadDataAsync(address, tcs);
}
catch(Exception exc)
{
// If something goes wrong kicking off the async work,
// unregister the callback and cancel the created task
webClient.DownloadDataCompleted -= handler;
tcs.TrySetException(exc);
}
// Return the task that represents the async operation
return tcs.Task;
}
Похожие вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.
List<Task<string>> tasks = new List<Task<string>>(); foreach (string url in urls) { Task<string> task = Download(url); tasks.Add(task); } Task.Factory.ContinueWhenAll(tasks.ToArray(), ConcurrentTasksCompleted);