如何在async / await maneer中为每个任务分配自己的延续而无需等待其他任务? [英] How do I assign own continuation to each task in the async/await maneer without one waiting the others ?
问题描述
我的问题如下:
我有n个并行运行的任务。
我希望每个Task都有自己的继续使用结果。 (想想UI更新,对于每个完成的任务)
如果我只使用Framework 4.0 Task,我会在每个任务上使用ContinueWith。
但是我想使用await / async,并且在每个任务完成后我找不到办法做某事,没有人等着另一个。
要转换的代码示例:
Hi,
My issue is the following :
I have n Tasks that run in parallel.
I want each Task to have its own continuation that uses the result. (Think of a UI update, for each finished task)
If I were only using Framework 4.0 Task, I would use the ContinueWith on each task.
But I want to use await / async , and I don't find a way to do something after each task is finished, without one waiting the other.
An example of code to transform :
public async void MainMethod()
{
var doSomething = DoSomething();
var doSomethingElse = DoSomethingElse();
var doSomethingDifferent = DoSomethingDifferent();
//These three continuations do not interfer with each other.
doSomething.ContinueWith(task => ReactToDoSomething(task.Result));
doSomethingElse.ContinueWith(task => ReactToDoSomethingElse(task.Result));
doSomethingDifferent.ContinueWith(task=>ReactToDoSomethingDifferent(task.Result));
}
public Task<int> DoSomething()
{
return Task.FromResult(1);
}
public Task<int> DoSomethingElse()
{
return Task.FromResult(2);
}
public Task<int> DoSomethingDifferent()
{
return Task.FromResult(3);
}
///The code of the react methods must not change.
public void ReactToDoSomething(int i)
{
//Update a part of UI
}
public void ReactToDoSomethingElse(int i)
{
//Update a part of UI
}
public void ReactToDoSomethingDifferent(int i)
{
//Update a part of UI
}
}
感谢您的帮助。
我尝试了什么:
首先我的想法是更换反应代码方法,但后来它是一个限制:不要改变这部分代码。 (在其他地方使用)
不过,这就是我的所作所为:
Thanks for your help.
What I have tried:
First my idea was to replace the code of the reacts methods, but then it came that it is a limitation : do not change this part of code. (Used somewhere else)
Still, here is what I did :
public class MyClass
{
public async void MainMethod()
{
var doSomething = DoSomething();
var doSomethingElse = DoSomethingElse();
var doSomethingDifferent = DoSomethingDifferent();
//These three continuations do not interfer with each other.
ReactToDoSomething(doSomething);
ReactToDoSomethingElse(doSomethingElse);
ReactToDoSomethingDifferent(doSomethingDifferent);
}
public Task<int> DoSomething()
{
return Task.FromResult(1);
}
public Task<int> DoSomethingElse()
{
return Task.FromResult(2);
}
public Task<int> DoSomethingDifferent()
{
return Task.FromResult(3);
}
//Changed React methods but must not, and this is my issue.
public async Task ReactToDoSomething(Task<int> task)
{
//Update a part of UI
}
public async void ReactToDoSomethingElse(Task<int> task)
{
//Update a part of UI
}
public async void ReactToDoSomethingDifferent(Task<int> task)
{
//Update a part of UI
}
}
推荐答案
你只需要等待
继续方法中的任务。
您可能还想等待所有延续完成MainMethod
。
You just need toawait
the task in the continuation methods.
You'll probably also want to wait for all of the continuations to finish in yourMainMethod
.
public async Task ReactToDoSomething(Task<int> task)
{
int result = await task;
// Do something here...
}
// Same for other "react to" methods...
public async Task MainMethod()
{
Task<int> doSomething = DoSomething();
Task<int> doSomethingElse = DoSomethingElse();
Task<int> doSomethingDifferent = DoSomethingDifferent();
Task continuation1 = ReactToDoSomething(doSomething);
Task continuation2 = ReactToDoSomethingElse(doSomethingElse);
Task continuation3 = ReactToDoSomethingDifferent(doSomethingDifferent);
await Task.WhenAll(continuation1, continuation2, continuation3);
}
编辑:如评论中所述,如果你不这样做我想改变原来的ReactTo方法,你需要一个包装方法来继续:
As discussed in the comments, if you don't want to change the original "ReactTo" methods, you'll need a wrapper method for the continuation:
private async Task ReactTo<TResult>(Task<TResult> task, Action<TResult> react)
{
TResult value = await task;
react(value);
}
public async Task MainMethod()
{
Task<int> doSomething = DoSomething();
Task<int> doSomethingElse = DoSomethingElse();
Task<int> doSomethingDifferent = DoSomethingDifferent();
Task continuation1 = ReactTo(doSomething, ReactToDoSomething);
Task continuation2 = ReactTo(doSomethingElse, ReactToDoSomethingElse);
Task continuation3 = ReactTo(doSomethingDifferent, ReactToDoSomethingDifferent);
await Task.WhenAll(continuation1, continuation2, continuation3);
}
将
类
重组为最好是一个好主意便于使用基于任务的异步模式。我建议你改变一些方法的签名。应为事件处理程序保留Async void
方法。我的建议是这样的。
It may be a good idea to restructure your
class
to facilitate using the Task-based Asynchronous Pattern. I suggest that you change the signatures of some of your methods.Async void
methods should be reserved for event handlers. My suggestion would be something like this.
public async Task MainMethod()
{
List<Task> tasks = new List<Task>() {
DoSomething(),
DoSomethingElse(),
DoSomethingDifferent() };
await Task.WhenAll(tasks);
}
public async Task DoSomething()
{
int result= await Task.FromResult(1);
if(result>0)
ReactToDoSomething(result);
}
public void ReactToDoSomething(int i)
{
//Update a part of UI
}
这篇关于如何在async / await maneer中为每个任务分配自己的延续而无需等待其他任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!