当前位置: 首页 > 编程语言 > C#

一次启动多个async-await函数并分别处理分享

时间:2023-04-10 11:49:19 C#

一次启动多个async/await函数并分别处理如何一次启动多个HttpClient.GetAsync()请求并返回他们各自的回应之后立即处理他们?我尝试的第一件事是:varresponse1=awaitclient.GetAsync("http://example.com/");varresponse2=awaitclient.GetAsync("http://stackoverflow.com/");处理示例(响应1);处理堆栈溢出(响应2);但当然它仍然是连续的。然后我尝试立即启动它们:vartask1=client.GetAsync("http://example.com/");vartask2=client.GetAsync("http://stackoverflow.com/");处理示例(等待任务1);HandleStackoverflow(等待任务2);现在任务是同时启动的,这很好,但是代码当然还是需要一个接一个地等待。我想要的是能够在“example.com”响应传入时立即对其进行处理,并在“stackoverflow.com”响应传入时对其进行处理。我可以将这两个任务放在一个数组中,在循环中使用Task.WaitAny(),检查哪个任务完成并调用适当的处理程序,但是……这比常规的旧回调更好吗?或者这不是async/await的预期用例?如果没有,我将如何将HttpClient.GetAsync()与回调一起使用?澄清一下——我所追求的行为就像这样的伪代码:client.GetAsyncWithCallback("http://example.com/",HandleExample);client.GetAsyncWithCallback("http://stackoverflow.com/",HandleStackoverflow);您可以使用ContinueWith和WhenAll等待新任务,task1和task2将并行执行vartask1=client.GetAsync("http://example.com/").ContinueWith(t=>HandleExample(t.结果));vartask2=client.GetAsync("http://stackoverflow.com/").ContinueWith(t=>HandleStackoverflow(t.Result));varresults=awaitTask.WhenAll(new[]{task1,task2});您可以使用一种在完成时重新排序的方法。这是JonSkeet和StephenToub描述的一个很好的技巧,我的AsyncEx库也支持它。所有三个实现都非常相似。获取我自己的实施://////创建一个新的按顺序完成的任务数组。//////任务结果的类型。///按完成排序的任务。publicstaticTask[]OrderByCompletion(thisIEnumerable>tasks){//这是JonSkeet的方法和StephenToub的方法的组合://http://msmvps.com/blogs/jon_skeet/archive/2012/01/16/eduasync-part-19-ordering-by-completion-ahead-of-time.aspx//http://blogs.msdn.com/b/pfxteam/archive/2012/08/02/processing-tasks-as-they-complete.aspx//具体化源任务序列。vartaskArray=tasks.ToArray();//分配一个TCS数组和一个结果任务数组。varnumTasks=taskArray.Length;vartcs=newTaskCompletionSource[numTasks];varret=newTask[numTasks];//当每个任务完成时,完成下一个tcs。intlastIndex=-1;行动>继续=任务=>{varindex=Interlocked.Increment(reflastIndex);tcs[索引].TryCompleteFromCompletedTask(任务);};//充满取出数组并附加延续。for(inti=0;i!=numTasks;++i){tcs[i]=newTaskCompletionSource();ret[i]=tcs[i].任务;taskArray[i].ContinueWith(continuation,CancellationToken.None,TaskContinuationOptions.ExecuteSynchronously,TaskScheduler.Default);返回ret;然后你可以像这样使用它:vartasks=new[]{client.GetAsync("http://example.com/"),client.GetAsync("http://stackoverflow.com/"),};varorderedTasks=tasks.OrderByCompletion();foreach(vartaskinorderedTasks){varresponse=awaittask;处理响应(响应);另一种方法是使用TPLDataflow;当每个任务完成时,将其操作发布到ActionBlock,如下所示:varblock=newActionBlock(HandleResponse);vartasks=new[]{client.GetAsync("http://example.com/"),client.GetAsync("http://stackoverflow.com/"),};foreach(vartaskintasks){task.ContinueWith(t=>{if(t.IsFaulted)((IDataflowBlock)block).Fault(t.Exception.InnerException);elseblock.Post(t.Result);});上面的任何一个答案都可以正常工作如果您的其余代码使用/可以使用TPL数据流,那么您可能更喜欢该解决方案。声明异步函数并传递回调:voidasyncGetAndHandleAsync(stringurl,Actioncallback){varresult=awaitclient.GetAsync(url);回调(结果);然后多次调用即可:以上是C#学习教程:一次启动多个async/await函数,分别处理它们共享的所有内容。如果对大家有用,需要了解更多C#学习教程,希望大家多多关注—GetAndHandleAsync("http://example.com/",HandleExample);GetAndHandleAsync("http://stackoverflow.com/",HandleStackoverflow);本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:

猜你喜欢