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

C# 我应该在后台线程中使用异步方法吗?,c#,.net,vb.net,multithreading,asynchronous,C#,.net,Vb.net,Multithreading,Asynchronous,我已经在这个话题上做了很多研究,但是有很多东西需要考虑,我不确定什么最适合我的情况 我正在制作运行多个“任务”的.NET应用程序(不是.NET意义上的任务,只是我使用的词)。每个任务都需要连续执行若干操作,直到取消为止。通常涉及套接字连接或HttpWebRequests 当前设置如下所示;当任务启动时,它会创建多个线程,通常是100-1000个线程。这些线程都运行相同的子例程,其中包含与该应用程序相关的操作的循环 因为我同时运行大量的HttpWebRequest/Socket连接,所以我希望尽可

我已经在这个话题上做了很多研究,但是有很多东西需要考虑,我不确定什么最适合我的情况

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

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

因为我同时运行大量的HttpWebRequest/Socket连接,所以我希望尽可能最好地平衡所有CPU核上的负载。目前,我使用HttpWebRequest的同步GetResponse方法。因为这是在后台线程中发生的,所以我不关心线程被阻塞,因为我需要HttpWebResponse来继续线程操作。如果我改用wait-GetResponseAsync方法,这会让操作系统更好地平衡负载吗


最后,我想知道在后台线程中等待异步方法是否有意义,还是会无缘无故地使代码更加复杂?如果没有意义,那么使用异步代码比只在后台线程中执行任务有什么好处?

异步/等待与线程不同。100-1000个线程是很多的,尤其是对于仅仅做I/O来说

如果在后台线程中使用Async,它可以减少必要的线程数。然而,从你目前的描述来看,我同意其他评论者的看法,即听起来根本不需要背景线程

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

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

await client.GetAsync(..);
await client.PostAsync(..); // doesn't post until the get completes
await client.GetAsync(..); // doesn't get until the post completes
若要执行并行工作,请收集任务,然后将其传递给
任务。所有

List<Task> tasks = new List<Task>();
for (int i = 0; i != 1000; ++i)
{
  Task task = DoMyOperationAsync();
  tasks.Add(task);
}
await Task.WhenAll(tasks);
List tasks=newlist();
对于(int i=0;i!=1000;++i)
{
Task Task=DoMyOperationAsync();
任务。添加(任务);
}
等待任务。何时(任务);

您可能会发现我的帮助。

如果我错了,请纠正我的错误,但是每个线程不是占用1 MiB的堆栈空间吗?@MattWilko这怎么可能?通常,许多线程都会循环一个复杂的操作,比如说我得到了第X页,然后发布了第Y页,得到了第Z页,等等。如果部分失败,它通常会再次开始循环。在一个线程上使用异步方法,我假设我开始异步获取第X页1000次,然后在回调中转到下一部分(第Y页后),如果某个部分失败,我将如何“重新循环”?@MattWilko我相信我理解该部分,问题是我不能只运行一个循环,因为它不能满足我的需要。假设我必须使用httpwebrequest连续获得5个页面,这将构成“成功”。然而,我需要这样做,直到我说,10000次成功。我不能让它把那5页拿出来,然后循环再开始拿,这会花很长时间。这就是为什么目前我有1000个线程执行相同的循环。如何将1000个线程的工作/速度合并为1?@Dirk Correct。根据Jeffrey Richter的说法:“CLR via C#-Third Edition”第五部分线程,第693页,“……当托管应用程序创建线程时,CLR强制Windows立即保留并完全提交堆栈,因此在创建每个线程时会完全分配1 MB的物理存储。”谢谢,我将尝试一下。我知道如何使用wait,只是不知道如何捆绑一堆wait操作并同时运行它们。