我正在实施一些异步工作并且无法提供帮助,但我觉得我最终会得到一个非常难看的结构,我想知道是否以及如何将其重写为“#”;感觉更好'。
var tasks = new List<Task>();
var t1 = new Task<Guid>(() => DoSomeStuff<Xyz>(dtx, e1, M1));
var t2 = new Task<Guid>(() => DoSomeStuff<Qrs>(dtx, e2, M2));
var t3 = new Task<Guid>(() => DoSomeStuff<Abc>(dtx, e3, M3));
tasks.Add(t1);
tasks.Add(t2);
tasks.Add(t3);
tasks.ForEach(x => x.Start());
Task.WaitAll(tasks.ToArray<Task>());
returnDto.t1value = t1.Result;
returnDto.t2value = t2.Result;
returnDto.t3value = t3.Result;
为简洁起见,变量名称已被更改,实际上还有更多任务。 任务都可以独立运行,但所有任务都必须在我们继续之前完成。
DoSomeStuff
看起来像这样:
private Guid DoSomeStuff<T>(DependentTransaction dtx, T thing, Func<T, Guid> method)
答案 0 :(得分:5)
使用async-await
异步等待,Task.WhenAll
等待多个任务并获得结果并Task.Run
并行运行DoSomeStuff
会更容易:< / p>
Guid[] results = await Task.WhenAll(
Task.Run(() => DoSomeStuff<Xyz>(dtx, e1, M1)),
Task.Run(() => DoSomeStuff<Qrs>(dtx, e2, M2)),
Task.Run(() => DoSomeStuff<Abc>(dtx, e3, M3)));
答案 1 :(得分:1)
我正在实施一些异步工作
区分异步和并行工作非常重要。异步工作通常是基于I / O的,而并行工作则使用多个线程来处理CPU绑定的代码。
如果您的工作是异步的,那么您应该使用异步API将DoSomeStuff
转换为async
方法。完成后,进行并发异步工作相对容易:
Guid[] results = await Task.WhenAll(DoSomeStuffAsync<Xyz>(dtx, e1, M1),
DoSomeStuffAsync<Qrs>(dtx, e2, M2), DoSomeStuffAsync<Abc>(dtx, e3, M3));
但是,如果您的工作是并行的,那么最好使用Parallel
类(或并行LINQ):
Guid[] results = new Guid[3];
Parallel.Invoke(() => { results[0] = DoSomeStuff<Xyz>(dtx, e1, M1); },
() => { results[1] = DoSomeStuff<Qrs>(dtx, e2, M2); },
() => { results[2] = DoSomeStuff<Abc>(dtx, e3, M3); });