异步调用的任务限制? [英] Task Limit for Async Calls?

查看:47
本文介绍了异步调用的任务限制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个同步工作的 .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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆