【问题标题】:Task List with parameters带参数的任务列表
【发布时间】:2015-02-22 16:37:17
【问题描述】:

我需要创建一个任务列表来执行一个带有一个参数的例程,然后等待这些任务完成,然后再继续执行其余的程序代码。这是一个例子:

List<Task> tasks = new List<Task>();
foreach (string URL in LIST_URL_COLLECTION)
{
    tasks[i] = Task.Factory.StartNew(
        GoToURL(URL)
        );
}
//wait for them to finish
Console.WriteLine("Done");

我已经用谷歌搜索过这个网站,但我一直在死胡同,我这样做过一次,但不记得是怎么做到的。

【问题讨论】:

  • 那么您在Task 类型中看到了什么?它有什么说“等待任务完成”吗? (您可能还想查看 Task.WhenAllTask.WaitAll,但我的意思是,如果您已经阅读了 Task 文档,那么您不应该已经走到了死胡同。)
  • 我花了几个小时试图弄清楚这件事。有些人比其他人更容易找到这些东西。我已经阅读了很多半答案,我只想得到一个完整的答案有人告诉我它是如何完成的

标签: c# .net task-parallel-library async-await dotnet-httpclient


【解决方案1】:

Task Parallel Library 公开了一种通过Task.WhenAll 方法异步等待所有任务完成的便捷方式。该方法本身返回一个Task,它是可等待的,应该等待:

public async Task QueryUrlsAsync()
{
    var urlFetchingTasks = ListUrlCollection.Select(url => Task.Run(url));
    await Task.WhenAll(urlFetchingTasks);
    Console.WriteLine("Done");
}

请注意,为了await,您的方法必须在方法签名中使用async 修饰符标记并返回Task(如果它没有返回值)或Task&lt;T&gt;(如果它确实有返回值,类型是T)。

附带说明,您的方法看起来像是在获取 url,我假设它正在向某个端点生成 Web 请求。为此,无需通过Task.Factory.StartNewTask.Run 使用额外的线程,因为这些操作自然是异步的。您应该以HttpClient 为起点。例如,您的方法可能如下所示:

public async Task QueryUrlsAsync()
{
    var urlFetchingTasks = ListUrlCollection.Select(url => 
                           {
                               var httpClient = new HttpClient();
                               return httpClient.GetAsync(url);
                           });

    await Task.WhenAll(urlFetchingTasks);
    Console.WriteLine("Done");
}

【讨论】:

    猜你喜欢
    • 2015-10-12
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    • 2018-08-29
    • 2013-09-10
    • 2017-08-02
    • 1970-01-01
    • 2013-07-16
    相关资源
    最近更新 更多