C# 使用任务的异步编程

C# 使用任务的异步编程,c#,asynchronous,async-await,C#,Asynchronous,Async Await,好的,我想保持简短和准确,我正试图找到最有效的方法来完成大量HttpWebRequests,但我有点困惑,如果我有一个任务列表,并且我使用Task.WaitAll函数等待所有任务完成,那么将列表中的任务(操作)也设为异步任务是否过份了呢?也许我可以用代码更好地解释自己: for (int i = 0; i < 50; i++) { taskList.Add(Task.Run(() => DoSomething()));

好的,我想保持简短和准确,我正试图找到最有效的方法来完成大量HttpWebRequests,但我有点困惑,如果我有一个任务列表,并且我使用Task.WaitAll函数等待所有任务完成,那么将列表中的任务(操作)也设为异步任务是否过份了呢?也许我可以用代码更好地解释自己:

        for (int i = 0; i < 50; i++)
        {
            taskList.Add(Task.Run(() => DoSomething()));
        }
        Task.WaitAll(taskList.ToArray());

公共任务DoSomething()
{
在这里写下等待响应、流等的请求
}
如果我已经将DoSomething函数发送到任务。Run函数是否已经意味着它正在线程池中自己的线程上运行?这意味着使DoSomething函数成为实际任务,并在该范围内实现waits/async功能变得多余?那不就是浪费更多的资源吗

如果我已经将DoSomething函数发送到任务。运行 函数不意味着它已经在它自己的线程上运行了吗 线程池意味着使剂量测量功能成为实际的 任务和实现该范围内的等待/异步功能 变得多余

相反-当您使用另一个线程(
Task.Run
)执行“不做任何事情”的方法(等待响应)时,您是在浪费资源

wait Task.Run(()=>DoSomethingSynchronously)
wait DoSomethingSynchronously()
是不同的事情,因为正确创建的
async wait
方法将在一个线程上执行。
在您的情况下,它将发送请求并将执行返回给调用方。响应到达后,它将在等待后继续执行

因此,使用
Task.Run
的方法什么都不做——只等待响应就变成了资源(线程)的浪费


因为您的
DoSomething
方法与外部资源(webservices)一起工作,所以您根本不需要担心线程池和线程。所有任务都可以通过
async wait
方法在一个线程中异步完成。

如果没有更多上下文,就无法回答。
DoSomething()
除了发出HTTP请求之外,还做其他事情吗?请求完成后,您是否需要it执行某些操作?如果您所做的只是请求,那么您应该使用异步请求API,从表示请求的
DoSomething()
任务返回
Task
,并将其添加到列表中,而不是使用
Task.Run()
。如果
DoSomething()
在请求后还有更多的处理要做,那么您也应该这样做,但您可以
在请求中等待。无论哪种方式,您都不太可能需要
Task.Run()
。但谁知道呢,因为您没有共享代码。因此,返回任务的函数已经在访问线程池中的线程,就好像我正在将非任务返回函数传递给任务一样。运行吗?所以Task.Run(()=>DoSomething());这与创建返回任务的函数相同?“返回任务的函数已经在访问线程池上的线程?”--不一定,不。但它是异步操作的,这正是您在上面代码中所关心的。不要混淆“异步”与“并发”或“线程化”。两者密切相关,但并不相同。存在不依赖于活动线程的异步机制。因此,最后一件事是,在对象集合上迭代并调用一个函数,该函数在每次迭代中返回一个任务并在该范围内等待,这与将task.Run(()=>NonTaskFunction)添加到任务列表中然后等待它的效果相同?但是,更优化、更“正确”的方法是实际使用任务api并实现适当的函数,是吗?在一组对象上迭代,我唯一要做的就是调用异步任务,这会给我一个parralel/多线程方面的结论,让异步任务DoSomething()包含waits并调用task.Run()=>DoSomething是完全无用和不必要的,因为正如函数签名所暗示的那样,任务已经在“运行”。我应该只使用Task。如果我有一个或多个函数需要在单独的线程上完成,并且说函数本身还不是任务,我想我没有完全理解你在3日试图说的话parahraph,但我会尽力澄清。有两种选择,要么一个接一个地等待任务,要么只是等待每个人。一个接一个地等待只是如果你真的想减少资源使用,或者与之前的任务结果有关。等待意味着“在继续之前完成所有事情”。无论您使用什么,您必须始终在方法末尾等待异步任务(除非将其向前移动到另一个方法),否则,您将遇到一个不好的竞速条件。@OriRefael,我不是说多个任务,在第三段中,我尝试了“rawly”解释异步方法可以在一个线程中执行。我想澄清当一个有多个任务时使用异步等待的方法。@OriRefael-如果有两个任务,如果第二个任务不依赖于第一个任务的结果-那么您可以几乎同时启动这两个任务,并在两个任务完成时“等待”:
await task.WhenAll(新[]{getOneAsync(),getAnotherAsync()})
如果第二个任务取决于第一个任务的结果,那么在开始第二个任务之前,您将首先“等待”:
var customerId=wait getCustomerIdAsync();wait getOrderByCustomerIdAsync(customerId);
这就是我说的:)我不是OP,也不是问问题的人
public void DoSomething()
{
Send off the HttpWebRequest here, with no awaits or any async programming
}
public Task<ResponseData> DoSomething()
{
Write the request here that awaits for responses, streams etc
}