【问题标题】:Skip the await task response conditional跳过等待任务响应条件
【发布时间】:2019-12-24 18:27:07
【问题描述】:

我有以下代码:

//Await #1

var response1 = await doSomething();

if(response1.isSuccess) {

//Await #2

var response2 = await doSomethingElse();

}

响应 1 和响应 2 完全独立,我想在这里并行化等待任务。 基本上响应 2 需要很多时间,因此只有在 response1 成功时才会调用。 有什么方法可以调用这两个任务并查看响应 1 的结果,如果失败,我会丢弃/跳过 Await#2 的响应。

【问题讨论】:

  • 你当前的代码没问题,只有在doSomething成功时才会调用doSomethingElse
  • 您的意思是要一起启动它们,但是如果响应 1 先完成,并且没有成功,您要取消响应 2?
  • 你可以使用任务工厂启动新任务,最后等待这两个任务。
  • @Sweeper,是的,这就是我正在尝试的。这可以实现吗?
  • 我认为你使用ContinueWith Task<string> t = Task.Run(() => doA()); t.ContinueWith((t1) => { doB(); });

标签: c#


【解决方案1】:

基本上你想要的是取消一个任务,但要多一点逻辑。

您需要编辑doSomethingElse 使其接受CancellationToken,并使用它来停止它的工作:

public async Task<Foo> DoSomethingElse(CancellationToken token) {
    ...
    if (token.IsCancellationRequested) {
        // stop what you are doing...
        // I can't tell you how to implement this without seeing how DoSomethingElse is implemented
    }
    ...
}

现在,从CancellationTokenSource 获取CancellationToken

var source = new CancellationTokenSource();
var token = source.Token;

这里是“如果响应1失败取消响应2”的逻辑:

var response2Task = DoSomethingElse(token);
var response1 = await DoSomething();
if (!response1.IsSuccess) {
    source.Cancel();
} else {
    var response2 = await response2Task;
}

【讨论】:

    【解决方案2】:
    var task2 = doSomethingElse();
    var response1 = await doSomething();
    
    if(response1.isSuccess) {
        var response2 = await task2;
    }
    

    这将立即开始执行doSomethingElse(),并仅在response1.isSuccess == true 时等待其完成

    【讨论】:

      【解决方案3】:

      您可以启动两个线程,然后一旦第一个任务获得结果,您可以停止或“等待”第二个线程完成。

      条件逻辑imo应该放在第一个任务的线程中。如果您无权访问 doSomething,请创建一个 lambda,您将在其中等待 doSomething 的响应,然后继续执行条件逻辑。

      如何停止线程? Here you gohere you go

      【讨论】:

        【解决方案4】:

        这是你可以做的:

                    var task1 = Task.Run(() =>
                    {
                        Console.WriteLine("running task 1");
                        return 1;
                    });
        
                    var task2 = Task.Run(() =>
                    {
                        Console.WriteLine("running task 2");
                        return 2;
                    });
        
                    await Task.WhenAll(task1, task2);
        

        因此,您将并行运行 2 个任务。如果您需要检查特定任务的结果,可以这样做(如果您之前运行Task.WhenAll(),它不会再次触发任务。它只会让您获得之前执行的任务的结果):

        var result1 = await task1;
        var result2 = await task2;
        

        然后你可以应用一些条件:

        if(result1 == 1) return result2;
        

        等等。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-05-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-22
          • 2013-10-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多