异步调用的任务限制? [英] Task Limit for Async Calls?
问题描述
我有一个同步工作的 .NET 4.5 WCF 客户端.我正在更新它以使用新的 async/await 功能来同时进行多个服务器调用以同时获取数据块.
I have a .NET 4.5 WCF client that works synchronously. I am updating it to use the new async/await functionality to make multiple simultaneous server calls to get chunks of data concurrently.
在我完成之前,我担心同时运行的所有线程会使服务器饱和(更不用说在我明年升级到 Azure 辅助角色时杀死我的 Azure 辅助角色).有没有办法集中管理我在类级别使用的任务线程总数?该代码与其他 WCF 客户端代码共享一个程序集.
Before i finish, I have a concern that all of the threads running at the same time will saturate the server (not to mention kill my Azure worker role when I upgrade to that next year). Is there a way to centrally govern the total amount of Task threads I use at the class level? The code shares an assembly with other WCF client code.
感谢所有的想法.
推荐答案
从字面上回答您的问题:您可以通过实现自己的 TaskScheduler 并将其分配给您创建的每个任务.微软甚至有一个完全可用的示例.
To answer your question literally: you can control the number of threads used to handle Tasks by implementing your own TaskScheduler and assigning it to every Task you create. Microsoft even has a fully working example.
不过,要回答根本问题:Task
并不意味着 Thread
.事实上,async/await 的主要目标是减少应用中的线程数.实际上,可以围绕 async/await 和 Tasks 设计一个完整的应用程序,运行数千个并发任务,并且只使用一个单线程.
To answer the underlying issue, though: Task
does not imply Thread
. In fact, the primary goal of async/await is to reduce the number of threads in your app. It's actually possible to have an entire app designed around async/await and Tasks, with thousands of concurrent tasks running, which uses only a single thread.
您希望您的代码在尽可能少的线程中运行,理想情况下不超过您拥有的逻辑 CPU 的数量,并且您希望 I/O 与您的代码同时发生.操作系统可以为您管理所有 I/O,而无需创建额外的线程.任务可帮助您完成此任务.
You want your code running in as few threads as possible, ideally no more than the number of logical CPUs you have, and you want the I/O to happen concurrently with your code. The OS can manage all that I/O for you without creating additional threads. Tasks help you accomplish this.
它可以为每个任务创建线程的唯一时间是,如果您正在模拟异步性,例如.调用 Task.Run 来运行阻塞代码.这种代码确实不明智:
The only time it could create a thread-per-task is if you're emulating asynchronicity, eg. calling Task.Run to run blocking code. This kind of code is indeed unwise:
Task t1 = Task.Run(()=>DownloadFile(url1));
Task t2 = Task.Run(()=>DownloadFile(url2));
await Task.WhenAll(t1, t2)
真正的异步代码(可以在单个线程中运行)要好得多,例如:
Truely asynchronous code (which could run in a single thread) is far better, eg:
Task t1 = DownloadFileAsync(url1);
Task t2 = DownloadFileAsync(url2);
await Task.WhenAll(t1, t2)
或者,对于任意数量的任务:
or, for an arbitrary number of tasks:
List<Task> tasks = new List<Task>();
foreach(string url in urls)
{
tasks.Add(DownloadFileAsync(url))
}
await Task.WhenAll(tasks);
这篇关于异步调用的任务限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!