我应该在后台线程中使用异步方法吗?

时间:2014-09-10 12:03:51

标签: c# .net vb.net multithreading asynchronous

我一直在就这个主题进行大量研究,但还有很多需要考虑的因素,我不确定哪种情况最适合我的情况。

我正在制作运行多个"任务的.NET应用程序" (不是.NET意义上的任务,只是我使用的单词)。每个任务都需要连续执行许多操作,直到取消。通常涉及套接字连接或HttpWebRequests。

目前的设置如下;当一个Task启动时,它会创建多个线程,通常是100-1000个线程。这些线程都运行相同的子例程,其中包含一个循环,其中包含与该应用程序相关的操作。

由于我同时运行大量HttpWebRequest / Socket连接,因此我希望尽可能平衡所有CPU内核的负载。目前我使用HttpWebRequest的同步GetResponse方法。由于这是在后台线程中发生的,所以我并不关心被阻塞的线程,因为我需要HttpWebResponse来继续线程操作。如果我使用Await GetResponseAsync方法,那么是否允许操作系统更好地平衡负载?

最终我想知道是否有必要在后台线程中等待异步方法,或者它是否使代码更加复杂无缘无故?如果没有意义,那么使用异步代码而不仅仅是在后台线程中完成工作有什么好处?

1 个答案:

答案 0 :(得分:1)

Async / Await与线程不同。 100-1000个线程是批次,特别是对于只进行I / O.

如果在后台线程中使用它,Async可以减少必需的线程数。但是,根据您当前的描述,我同意其他评论者的观点,这听起来根本没有任何需要背景线程。

Async / Await旨在遵循与常规代码相同的流程,因此如果您的代码使用try / catch重试失败,那么您的async代码将使用相同的代码try / catch等。

要执行序列化工作(“按顺序”),只需await返回的任务:

await client.GetAsync(..);
await client.PostAsync(..); // doesn't post until the get completes
await client.GetAsync(..); // doesn't get until the post completes

要进行并发工作,请收集任务,然后将其传递给Task.WhenAll

List<Task> tasks = new List<Task>();
for (int i = 0; i != 1000; ++i)
{
  Task task = DoMyOperationAsync();
  tasks.Add(task);
}
await Task.WhenAll(tasks);

您可能会发现我的async intro有帮助。