Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 异步等待vs TaskFactory.StartNew和WaitAll_C#_.net_Asynchronous_Task Parallel Library_Async Await - Fatal编程技术网

C# 异步等待vs TaskFactory.StartNew和WaitAll

C# 异步等待vs TaskFactory.StartNew和WaitAll,c#,.net,asynchronous,task-parallel-library,async-await,C#,.net,Asynchronous,Task Parallel Library,Async Await,我有一个NServiceBus主机,一旦收到关于某个特定用户帐户的消息,它就会去下载一大堆数据。一个数据文件大约是3Mb(myob-通过webservice调用),另一个大约是2Mb(restful端点,相当快!)。为了避免等待太久,我将两个下载调用打包如下: var myobBlock = Task.Factory.StartNew(() => myobService.GetDataForUser(accountId, datablockId, CurrencyFormat.Ignore

我有一个NServiceBus主机,一旦收到关于某个特定用户帐户的消息,它就会去下载一大堆数据。一个数据文件大约是3Mb(myob-通过webservice调用),另一个大约是2Mb(restful端点,相当快!)。为了避免等待太久,我将两个下载调用打包如下:

var myobBlock = Task.Factory.StartNew(() => myobService.GetDataForUser(accountId, datablockId, CurrencyFormat.IgnoreValidator));
var account = Task.Factory.StartNew(() => accountService.DownloadMetaAccount(accountId, securityContext));

Task.WaitAll(myobBlock, account);

var myobData = myobBlock.Result;
var accountData = account.Result;
//...Process AccountData Object using myobData object
我想知道使用新的async/await模式与我上面提到的TPL风格的方法相比有什么好处。阅读Stephen Clearys的笔记,上面的内容似乎会导致线程坐在那里等待,Async/Await将继续并释放线程以进行其他工作


您将如何在Async/Await的上下文中重写它,这是否有益?我们有很多账户需要处理,但每个账户(财年末报告)或每个请求(当客户打电话要求他们的报告时是临时的)都有一次MSMQ消息使用
async/await
的好处是提供了一个真正的异步api(不使用
Task.Run
等通过异步调用同步方法,但执行真正的异步I/O工作)您可以避免分配任何不必要的线程,这些线程只会浪费资源等待阻塞I/O操作

假设您的两个服务方法都公开了一个
async
api,您可以执行以下操作,而不是使用两个线程池线程:

var myobBlock = myobService.GetDataForUserAsync(accountId, datablockId, CurrencyFormat.IgnoreValidator));

var account = accountService.DownloadMetaAccountAsync(accountId, securityContext));

// await till both async operations complete
await Task.WhenAll(myobBlock, account);

将发生的情况是,执行将返回到调用方法,直到两个任务完成。当它们完成时,如果需要,将通过IOCP继续到分配的
SynchronizationContext

GetDataForUser和DownloadMetaAccount是否公开异步API?它们不公开,myobService是围绕第三方客户端acc的包装器CountService是我们的。您可以将GetDataForUser的响应包装在TaskCompletionSource中,但这意味着我必须将运行上述代码的方法修饰为async?我正在实现一个接口,该接口无法修改以下对象的方法签名:(通过使用异步,您可以在web服务工作期间保存三个被阻止的线程。如果您不需要保存它们,异步将不会给您带来任何好处。我发现最好从“离开”开始你可以重建你的web服务代理以获得异步方法,并使用REST API的
HttpClient
。有了这些,使你的服务方法异步是很简单的。这是一个很好的解释,Yuval,不幸的是我没有足够的勇气来支持你!@StephenCleary,有什么办法吗仍然使用async/await(特别是在YuvalItzchakov解释之后)而不触及代理或rest API吗?@Keerthi:如果这是一个服务器,那么不是。如果这是一个客户端应用,那么你可以“作弊”只需在<代码>任务中包装东西。运行< /COD>等待。另一个要考虑的解决方案是TPL数据流。@ Keththi,如果它足够好,满足您的需要,您可以将其标记为答案。