不直接返回任务时最适当使用异步/等待?

时间:2017-03-25 08:49:08

标签: c# asynchronous async-await task-parallel-library

我在代码中使用异步等待很多,但我发现我可能没有像我应该那样做得恰到好处。

我正在寻找确认我对处理异步/等待处理多种方法并且不直接返回任务结果的方法的最佳方法的理解。

当我只是想直接返回任务结果时,这就是我通常会做的事情。

    //basic - 1 thing to do - directly return task
    public Task<string> ReturningATask(string key)
    {
        return _cache.GetStringAsync(key);
    }

但是当我想在返回之前具有任务价值的东西时,我已经养成了异步方法和等待任务的习惯。< / p>

    //More than a single operation going on.
    //In this case I want to just return a bool indicating whether or not the key exists.
    public async Task<bool> ReturningABool(string key)
    {
        string foundValue = await _cache.GetStringAsync(key);

        if (string.IsNullOrEmpty(foundValue))
        {
            return false;
        }
        else
        {
            return true;
        }
    }

我觉得ContinueWith可能是处理这个问题的更合适的方式。

以下示例通常是可接受的处理方法吗? 我进入了我的脑袋&#34;从不使用task.Result因为它阻塞&#34;,但是使用ContinueWith,任务已经完成,所以没有阻止权利?

    //The more correct way?        
    public Task<bool> ReturningATaskBool(string key)
    {
        return _cache.GetStringAsync(key)
            .ContinueWith(x =>
            {
                if (string.IsNullOrEmpty(x.Result))
                {
                    return false;
                }
                else
                {
                    return true;
                }
            });
    }

感谢。

2 个答案:

答案 0 :(得分:5)

ContinueWith是一个危险的低级API。具体来说,它:

  • 不了解异步延续。
  • 使用当前 TaskScheduler(不是默认 TaskScheduler)作为其TaskScheduler参数的默认值。
  • 连续标志没有适当的默认行为(例如DenyChildAttach)。

await没有这些问题。您应该使用await代替ContinueWith

See my blog for an exhaustive (exhausting?) discussion

答案 1 :(得分:2)

大部分时间它没有太大的区别。 async/await的开销可能略高于ContinueWith(虽然它实际上取决于场景),但我怀疑这是你应该担心的问题。只需找到你觉得更容易阅读的那个。

唯一需要注意的是await会将延续发布到当前同步上下文(如果有)。如果你在winform / wpf应用程序中,这可能特别有用。另一方面,ContinueWith在当前任务调度程序(通常是线程池)上执行延续。

  

我陷入了脑海“永远不会使用task.Result因为它正在阻塞”,但是使用ContinueWith,任务已经完成,所以没有阻止权利吗?

这是正确的,你使用ContinueWith的方式很好。

相关问题