问题
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