异步调用的任务限制?

时间:2012-11-26 22:38:31

标签: multithreading wcf task

我有一个同步工作的.NET 4.5 WCF客户端。我正在更新它以使用新的async / await功能来同时进行多个服务器调用以获取数据块。

在我完成之前,我担心所有同时运行的线程都会使服务器饱和(更不用说在我升级到明年时杀死我的Azure工作者角色)。有没有办法集中管理我在类级别使用的任务线程的总量?代码与其他WCF客户端代码共享程序集。

感谢所有想法。

2 个答案:

答案 0 :(得分:2)

要按字面意思回答您的问题:您可以通过实施自己的TaskScheduler并将其分配给您创建的每个任务来控制用于处理任务的线程数。微软甚至有一个fully working example

要回答根本问题,Task并不意味着Thread。实际上,async / await的主要目标是减少应用程序中的线程数。它实际上可以围绕async / await和Tasks设计一个完整的应用程序,运行数千个并发任务,只使用单个线程。

您希望代码在尽可能少的线程中运行,理想情况下不超过您拥有的逻辑CPU数量,并且您希望I / O与代码同时发生。操作系统可以为您管理所有I / O,而无需创建其他线程。任务可以帮助您实现这一目标。

它可以创建每个任务的线程的唯一时间是你正在模仿异步性,例如。调用Task.Run来运行阻塞代码。这种代码确实是不明智的:

Task t1 = Task.Run(()=>DownloadFile(url1));
Task t2 = Task.Run(()=>DownloadFile(url2));

await Task.WhenAll(t1, t2)

真正的异步代码(可以在单个线程中运行)要好得多,例如:

Task t1 = DownloadFileAsync(url1);
Task t2 = DownloadFileAsync(url2);

await Task.WhenAll(t1, t2)

或者,对于任意数量的任务:

List<Task> tasks = new List<Task>();

foreach(string url in urls)
{
    tasks.Add(DownloadFileAsync(url))
}

await Task.WhenAll(tasks);

答案 1 :(得分:1)

在异步WCF服务器的上下文中,没有“任务线程”。

您有Task个实例代表正在进行的请求,但它们不是线程池线程。服务器将根据需要为有一些工作要求的请求分配线程池; <异步等待的请求(在await中)没有线程。