问题根源与解决方案
你遇到的核心问题不是OpenAsync没执行完成就跑后续代码,而是using语句的资源生命周期管理错误!当你在方法里return con.OpenAsync(...).ContinueWith(...)时,using块会在return语句执行后立刻释放SqlConnection和SqlCommand——但ContinueWith里的代码是在OpenAsync完成后才会执行的,这时候连接和命令已经被Dispose了,自然会抛出错误。
要实现用ContinueWith延续任务并返回带值的Task<T>,必须确保资源(连接、命令)在延续任务执行完成后再释放,不能用外层的using直接包裹。下面是具体的修正方案:
修正TestOption1(返回Task)
private static Task TestOption1(CancellationToken cancellationToken = default)
{
var con = new SqlConnection(Membership);
var cmd = con.CreateCommand();
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "set nocount on";
return con.OpenAsync(cancellationToken)
.ContinueWith(t =>
{
try
{
cmd.ExecuteNonQuery();
}
finally
{
// 执行完后手动释放资源
cmd.Dispose();
con.Dispose();
}
}, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
}
修正TestOptionReturn(返回Task