我读过一些关于等待和ContinueWith之间的区别的线程。但没人能完全回答我。
我有一个DataAccess层,它使用Dapper在数据库中插入记录。InsertAsync方法是:
public Task<int> InsertAsync(TEntity entity)
{
return Connection.InsertAsync(entity, Transaction).ContinueWith(r => Convert.ToInt32(r.Result));
}我不使用异步和等待,因为在我的头脑中,谁将使用这个方法将等待结果。是对的?
发布于 2021-05-21 08:48:25
我不使用异步和等待,因为在我的头脑中,谁将使用这个方法将等待结果。是对的?
那是不对的。虽然await关键字确实在调用Convert.ToInt32之前等待Connection.InsertAsync完成,但当它开始等待Connection.InsertAsync 时,它就将控制权释放回调用方。
换句话说,调用者将不会被困在等待Connection.InsertAsync完成。打电话的人会被告知“这需要一段时间,可以自由地做点别的事情”,这样就可以继续了。
现在,如果调用者自己被显式地告知您调用方法的同一行上的await InsertAsync(TEntity)方法,那么它将等待,并且它不会做任何其他事情(除了将控制释放回其调用方),但这是因为它被明确指示在此时等待。
要在代码中解释:
// I will wait for this result
var myInt = await Connection.InsertAsync(myEntity);
// I will not do this until I receive myInt
var sum = 1 + 1;
var anotherSum = 2 + 2;
var andAnotherSum = 3 + 3;如果没有await,调用方只需转到下一个命令并执行其工作,直到最终被告知必须await从InsertAsync(TEntity)返回的任务为止。
要在代码中解释:
// I will ask for this result but not wait for it
var myIntTask = Connection.InsertAsync(myEntity);
// I will keep myself busy doing this work
var sum = 1 + 1;
var anotherSum = 2 + 2;
var andAnotherSum = 3 + 3;
// My work is done. I hope the task is already done too.
// If not, I will have to wait for it because I can't put it off any longer.
var myInt = await myIntTask;我读过一些关于等待和ContinueWith之间的区别的线程。
从功能上讲,两者并无区别。然而,ContinueWith语法最近已不再受欢迎,而await语法更受青睐,因为它减少了嵌套并提高了可读性。
在等待方面,行为完全相同。
就我个人而言,我怀疑ContinueWith是最初尝试设计异步方法时遗留下来的工件,其方式与JS工作中承诺的方法相同,但这只是一种怀疑。
发布于 2021-05-21 08:42:28
应该没问题的。但是,有一项建议是Continue with,以避免在什么上下文中继续运行的任何含糊不清,即使在这种特殊情况下不重要。
我更喜欢这个版本
public async Task<int> InsertAsync(TEntity entity)
{
var r = await Connection.InsertAsync(entity, Transaction);
return Convert.ToInt32(r);
}我认为这更容易阅读,并且它将始终在与调用者相同的上下文中执行延续。在幕后,它将产生与您的示例非常相似的代码。
发布于 2021-05-21 08:54:01
与ContinueWith方法相比,您肯定更喜欢异步/等待。
public async Task<int> InsertAsync(TEntity entity)
{
var result = await Connection.InsertAsync(entity, Transaction);
return Convert.ToInt32(result);
}本原 ContinueWith方法具有许多隐藏的问题。同步抛出的异常、封装在AggregateException中的异常、不捕获的TaskScheduler.Current、未捕获的SynchronizationContext、未正确展开的嵌套Task<Task>,如果您养成了遵循ContinueWith路由的习惯,所有这些异常都会在某个点出现并咬你一口。
https://stackoverflow.com/questions/67633072
复制相似问题