C# 在不直接返回任务时最合适使用Async/Await?
我在代码中使用了很多async Wait,但我突然想到,我可能没有像应该做的那样恰当 我希望确认我对处理async/Wait的最佳方法的理解,该方法可以完成多项任务,并且不会直接返回任务结果 当我只想直接返回任务的结果时,我通常会这样做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
//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的引入之后,没有更好的选择了。