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

Ste*_*bob 1 c# asynchronous task-parallel-library async-await

我在我的代码中使用异步等待很多,但是我发现我可能没有像我应该那样适当地执行它.

我正在寻找确认我理解处理async/await的方法的最佳方法,这些方法执行多项操作并且不直接返回任务的结果.

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

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

但是当我想在返回之前对任务的价值一些事情时,我已经养成了异步方法和等待任务的习惯.

    //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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

在我看来,ContinueWith可能是处理这个问题的更合适的方法.

以下示例通常是可接受的处理方式吗?我进入了脑海"永远不会使用task.Result,因为它正在阻塞",但是使用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;
                }
            });
    }
Run Code Online (Sandbox Code Playgroud)

谢谢.

Ste*_*ary 5

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

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

await没有这些问题.你应该使用await而不是ContinueWith.

请参阅我的博客,了解详尽(耗费精力?)的讨论.