C#学习教程:如何使用谓词实现Task.WhenAny()安全地。我需要在第一个任务成功完成或所有任务失败时完成。请指教。publicstaticTaskGetFirstResult(ICollection>>taskFactories,Predicatepredicate)whereT:class{vartcs=newTaskCompletionSource();varcts=newCancellationTokenSource();int完成计数=0;//如果你有很多任务,你可能需要限制它们//(例如,这样你就不会尝试同时发送99999999个请求)//请参阅:http://stackoverflow.com/a/25877042/67824foreach(vartaskFactoryintaskFactories){taskFactory(cts.Token).ContinueWith(t=>{if(t.Exception!=null){Console.WriteLine($"Taskcompletedwithexception:{t.Exception}");}elseif(predicate(t.Result)){cts.Cancel();tcs.TrySetResult(t.Result);}if(Interlocked.Increment(refcompletedCount)==taskFactories.Count){tcs.SetException(newInvalidOperationException("Alltasksfailed"));}},cts.Token);}返回tcs.Task;}产品使用方法:usingSystem.Net.Http;varclient=newHttpClient();varresponse=awaitGetFirstResult(newFunc>[]{ct=>client.Get异步(“http://microsoft123456.com”,ct),ct=>client.GetAsync(“http://microsoft123456.com”,ct),ct=>client.GetAsync(“http://microsoft123456.com",ct),ct=>client.GetAsync("http://microsoft123456.com",ct),ct=>client.GetAsync("http://microsoft123456.com",ct),ct=>客户端。GetAsync("http://microsoft123456.com",ct),ct=>client.GetAsync("http://microsoft123456.com",ct),ct=>client.GetAsync("http://microsoft.com",ct),ct=>client.GetAsync("http://microsoft123456.com",ct),ct=>client.GetAsync("http://microsoft123456.com",ct),},rm=>rm.IsSuccessStatusCode);Console.WriteLine($"响应成功:{response}");等待任何一个任务,满足条件则返回任务,否则等待其他任务,直到没有其他任务在等待。publicstaticasyncTaskWhenAny(IEnumerabletasks,Predicatecondition){vartasklist=tasks.ToList();while(tasklist.Count>0){vartask=awaitTask.WhenAny(tasklist);如果(条件(任务))返回任务;tasklist.Remove(任务);}返回空值;}简单检查一下vartasks=newList{Task.FromException(newException()),Task.FromException(newException()),Task.FromException(newException()),Task.CompletedTask,};varcompletedTask=WhenAny(tasks,t=>t.Status==TaskStatus.RanToCompletion).Result;if(tasks.IndexOf(completedTask)!=3)thrownewException("notexpected");publicstaticTask>WhenFirst(IEnumerable>tasks,Func,bool>predicate){if(tasks==null)thrownewArgumentNullException(nameof(tasks));if(predicate==null)thrownewArgumentNullException(nameof(predicate));vartasksArray=(tasksasIReadOnlyList>)??任务.ToArray();if(tasksArray.Count==0)thrownewArgumentException("空任务列表",nameof(tasks));if(tasksArray.Any(t=>t==null))thrownewArgumentException("Taskscontainsanullreference",nameof(tasks));vartcs=newTaskCompletionSource>();varcount=tasksArray.Count;Action>continuation=t=>{if(predicate(t)){tcs.TrySetResult(t);}if(Interlocked.Decrement(refcount)==0){tcs.TrySetResult(null);}};foreach(vartaskintasksArray){task.ContinueWith(continuation);}returntcs.Task;}示例用法:vartask=awaitWhenFirst(tasks,t=>t.Status==TaskStatus.RanToCompletion);if(task!=null)varvalue=awaittask;请注意,这不会传播失败任务的异常(就像WhenAny一样)谓词实现了Task.WhenAny()共享的所有内容。如果它对你有用并且需要了解更多C#学习教程的朋友,希望大家多多关注。本文采集自网络,不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
