【问题标题】:Correct way to run two tasks运行两个任务的正确方法
【发布时间】:2016-08-17 22:01:22
【问题描述】:

我想知道这种并行运行两个长时间运行的操作然后获得结果的方法是否正确,以及使用 async/await 是否有任何优势。

        public int DoStuff()
        {
            var res1 = Task.Run(() => LongRunning1());
            var res2 = Task.Run(() => LongRunning2());

            Task.WhenAll(res1, res2);
            return res1.Result + res2.Result;
        }

        int LongRunning1()
        {
            Thread.Sleep(30);
            return 10;
        }

        int LongRunning2()
        {
            Thread.Sleep(10);
            return 20;
        }

【问题讨论】:

  • 在这两个长期运行的操作中是否还有其他事情发生?
  • 长时间运行的操作是否受 IO 或 CPU 限制?

标签: c# multithreading asynchronous async-await


【解决方案1】:

以这种方式并行运行任务很好。 WhenAll 行什么都不做,可以删除。另请注意,Result 将在AggregateException 中包装任何异常;这是运行并行代码时的正常现象。

public int DoStuff()
{
  var res1 = Task.Run(() => LongRunning1());
  var res2 = Task.Run(() => LongRunning2());

  return res1.Result + res2.Result;
}

但是,如果任务自然是异步的(例如,I/O-bound),那么您可以使用并发异步代码代替并行代码:

async Task<int> LongRunning1Async()
{
  await Task.Delay(30);
  return 10;
}

async Task<int> LongRunning2Async()
{
  await Task.Delay(10);
  return 20;
}

public async Task<int> DoStuffAsync()
{
  var res1 = LongRunning1Async();
  var res2 = LongRunning2Async();

  return await res1 + await res2;
}

或者,或者:

public async Task<int> DoStuffAsync()
{
  var res1 = LongRunning1Async();
  var res2 = LongRunning2Async();

  var results = await Task.WhenAll(res1, res2);
  return results[0] + results[1];
}

【讨论】:

  • 任务是http请求。仍然推荐 async/await 吗?与 .Result 方法相比有什么优势?
  • @Cyan:HTTP 请求是 I/O,所以是的,您应该使用异步并发而不是并行。优点是您使用更少的线程来完成相同的结果。
  • 还有一个问题@Stephen:在你的博客上blog.stephencleary.com/2012/07/dont-block-on-async-code.html 你是说.Result 可能导致死锁。为什么不在上面的代码中?
  • @Cyan:第一个代码示例使用task parallelism,其中Result 是合适的(并且不会死锁,因为任务实际上是在同步代码上运行其他线程)。后两个示例使用异步并发,其中Result 应替换为await
  • @Cyan:如果可能,您应该使用异步 API。这允许您使用异步并发,它的扩展性比并行性好得多。但如果您使用同步 API,那么您可以使用并行性。
猜你喜欢
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-15
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多