如何在async / await maneer中为每个任务分配自己的延续而无需等待其他任务? [英] How do I assign own continuation to each task in the async/await maneer without one waiting the others ?

查看:77
本文介绍了如何在async / await maneer中为每个任务分配自己的延续而无需等待其他任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我的问题如下:

我有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 to await the task in the continuation methods.

You'll probably also want to wait for all of the continuations to finish in your MainMethod.
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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆