Task Limit for Async Calls?

社会主义新天地 提交于 2019-12-10 22:06:42

问题


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.

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.

Thanks for all ideas.


回答1:


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.

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.

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.

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);



回答2:


In the context of asynchronous WCF servers, there are no "Task threads".

You have Task instances that represent in-progress requests, but they are not thread pool threads. The server will allocate thread pools as needed to requests that have some work to do; a request that is asynchronously waiting (in an await) does not have a thread.



来源:https://stackoverflow.com/questions/13574377/task-limit-for-async-calls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!