C# 差异等待并继续

C# 差异等待并继续,c#,.net-core,async-await,C#,.net Core,Async Await,我读过一些关于等待和继续之间区别的帖子。但没有人能完全回答我 我有一个DataAccess层,它使用Dapper在数据库中插入记录。 InsertAsync方法是: public Task<int> InsertAsync(TEntity entity) { return Connection.InsertAsync(entity, Transaction).ContinueWith(r => Convert.ToInt32(r.Result)); } 公共任务插入同步(TE

我读过一些关于等待和继续之间区别的帖子。但没有人能完全回答我

我有一个DataAccess层,它使用Dapper在数据库中插入记录。 InsertAsync方法是:

public Task<int> InsertAsync(TEntity entity)
{
return Connection.InsertAsync(entity, Transaction).ContinueWith(r => Convert.ToInt32(r.Result));
}
公共任务插入同步(TEntity实体)
{
返回Connection.InsertAsync(实体,事务).ContinueWith(r=>Convert.ToInt32(r.Result));
}
我不使用async和Wait,因为在我的头脑中,谁将使用这种方法,谁将等待结果。
正确吗?

应该可以。然而,有一项建议是,为了避免继续将在什么样的背景下运行的任何模糊性,即使在这种特殊情况下并不重要

我更喜欢这个版本

public async Task<int> InsertAsync(TEntity entity)
{
    var r = await Connection.InsertAsync(entity, Transaction);
    return Convert.ToInt32(r);
}
公共异步任务插入同步(tenty实体)
{
var r=等待连接.InsertAsync(实体,事务);
返回转换为32(r);
}

我认为这更容易阅读,它总是在与调用方相同的上下文中执行延续。在幕后,它将生成与您的示例非常相似的代码

我不使用async和Wait,因为在我的头脑中,谁将使用这种方法,谁将等待结果。对吗

这是不对的。虽然
await
关键字确实在调用
Convert.ToInt32
之前等待
Connection.InsertAsync
完成,但在它开始等待
Connection.InsertAsync
时,它会将控制权释放回调用方

换句话说,调用者不会被困在等待
Connection.InsertAsync
完成。来电者会被告知“这需要一段时间,请随意做其他事情”,以便继续

现在,如果调用方自己被明确告知在调用该方法的同一行上等待
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;
// 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;
如果没有
wait
,调用方将继续执行下一个命令并执行其工作,直到最后被告知必须
wait
InsertAsync(tenty)
返回的任务为止

要用代码解释:

// 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;
// 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
语法最近已不受欢迎,而
await
语法更受欢迎,因为它减少了嵌套并提高了可读性

在等待方面,行为完全相同


就我个人而言,我怀疑
ContinueWith
是最初尝试以JS工作中承诺的相同方式设计异步方法时留下的遗留产物,但这只是一种怀疑。

你肯定应该更喜欢async/wait而不是
ContinueWith
方法

public async Task<int> InsertAsync(TEntity entity)
{
    var result = await Connection.InsertAsync(entity, Transaction);
    return Convert.ToInt32(result);
}
公共异步任务插入同步(tenty实体)
{
var result=await Connection.InsertAsync(实体、事务);
返回Convert.ToInt32(结果);
}

ContinueWith
方法已禁用。异常同步抛出,异常包装在
AggregateException
s,
TaskScheduler中。当前的
模糊性,
SynchronizationContext
未捕获,嵌套的
任务
s未正确展开,都会在某一点或另一点上咬到你,如果你养成了沿着
路线继续走下去的习惯。

也许这是C#5之前的代码。它本质上与
var result=wait Connection.InsertAsync(…)相同;返回Convert.ToInt32(结果)等待行之后的所有内容都是一个延续。因此,除非您还想将.NET4.0作为目标,否则最好使用AsyncAwait,它更干净。谢谢,代码在.NET5中。我切换到异步,等待尽快通知您。你的例子很清楚。我唯一的疑问是在一个不是GUI的层中使用async/await,但您向我解释了这是正确的。
ContinueWith
也是一种非常低级的方法。具体地说,它不理解
async
委托,并且具有令人困惑的默认调度行为<代码>等待
是一种更安全的替代方案,它也使代码更易于维护。