C# 在不直接返回任务时最合适使用Async/Await?

C# 在不直接返回任务时最合适使用Async/Await?,c#,asynchronous,async-await,task-parallel-library,C#,Asynchronous,Async Await,Task Parallel Library,我在代码中使用了很多async Wait,但我突然想到,我可能没有像应该做的那样恰当 我希望确认我对处理async/Wait的最佳方法的理解,该方法可以完成多项任务,并且不会直接返回任务结果 当我只想直接返回任务的结果时,我通常会这样做 //basic - 1 thing to do - directly return task public Task<string> ReturningATask(string key) { return _c

我在代码中使用了很多async Wait,但我突然想到,我可能没有像应该做的那样恰当

我希望确认我对处理async/Wait的最佳方法的理解,该方法可以完成多项任务,并且不会直接返回任务结果

当我只想直接返回任务的结果时,我通常会这样做

    //basic - 1 thing to do - directly return task
    public Task<string> ReturningATask(string key)
    {
        return _cache.GetStringAsync(key);
    }
然而,当我想在返回之前对任务的值做一些事情时,我习惯于异步该方法并在其中等待任务

    //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可能是处理这个问题的更合适的方法

下面的例子是普遍接受的处理方法吗? 我想我从来没有使用过任务。结果是它被阻塞了,但是使用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;
                }
            });
    }

谢谢。

大多数情况下,这没什么区别。async/await的开销可能比ContinueWith稍大一些,尽管这实际上取决于场景,但我怀疑这是您应该担心的。只要选一个你觉得更容易阅读的

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

我想我从来没有使用过任务。结果是它被阻塞了,但是使用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;
                }
            });
    }

没错,您使用ContinueWith的方式很好

大多数情况下,这没有多大区别。async/await的开销可能比ContinueWith稍大一些,尽管这实际上取决于场景,但我怀疑这是您应该担心的。只要选一个你觉得更容易阅读的

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

我想我从来没有使用过任务。结果是它被阻塞了,但是使用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;
                }
            });
    }
没错,您使用ContinueWith的方式很好

ContinueWith是一种危险的低级API。具体而言,它:

不理解异步延续。 使用当前TaskScheduler而不是默认TaskScheduler作为其TaskScheduler参数的默认值。 没有适用于继续标志的默认行为,例如DenyChildatach。 Wait没有这些问题。你应该使用wait而不是ContinueWith

.ContinueWith是一种危险的低级API。具体而言,它:

不理解异步延续。 使用当前TaskScheduler而不是默认TaskScheduler作为其TaskScheduler参数的默认值。 没有适用于继续标志的默认行为,例如DenyChildatach。 Wait没有这些问题。你应该使用wait而不是ContinueWith


.

您使用async/await返回任务。是的,对不起,您说得很对,我说错了。我想我把我的第二个代码示例搞砸了,因为我通常只会将其设置为一个异步bool,而不是一个当然不会返回任务的异步任务。已编辑问题以删除该位。您可以执行返回操作!string.IsNullOrEmptyx.resulty您确实使用async/await返回任务。是的,对不起,您说得很对,我说错了。我想我把我的第二个代码示例搞砸了,因为我通常只会将其设置为一个异步bool,而不是一个当然不会返回任务的异步任务。已编辑问题以删除该位。您可以执行返回操作!我担心ContinueWith会有一些问题,比如异常处理。我将坚持我习惯的等待方式。@Steviebob ContinueWith在引入Async await之前就已经存在,并且作为一种解决办法用于异步实现,它是无阻塞的,比APM简单得多。现在介绍async await之后,没有更好的选项了。嗯,我担心ContinueWith可能会有一些问题,比如异常处理。我将坚持我习惯的等待方式。@Steviebob ContinueWith在引入Async await之前就已经存在,并且作为一种解决办法用于异步实现,它是无阻塞的,比APM简单得多。现在,在async await的引入之后,没有更好的选择了。