我已经读过,当我完全确定操作已完成时,我应该只使用Result
而不是await
。我不确定下面会发生什么,并且想问一下有经验的程序员,如果这是await
/ Result
/ async
的完全安全使用。
public static bool Success()
{
return 0 < Execute("DELETE FROM Table WHERE Id = 12").Result;
}
public static async Task<int> Execute(string sql)
{
using (var con = Connection)
{
con.Open();
return await con.ExecuteAsync(sql);
}
}
答案 0 :(得分:4)
这不安全。使用Task.Result
当你调用异步方法时,它会同步运行,直到它到达await,然后返回给调用者,并带有代表异步操作的任务。
任务未完成,使用Task.Result
将阻止调用线程。
您应该等待返回的任务,或使用同步选项。
public static Task<bool> SuccessAsync()
{
return 0 < await ExecuteAsync("DELETE FROM Table WHERE Id = 12");
}
public static async Task<int> ExecuteAsync(string sql)
{
using (var con = Connection)
{
con.Open();
return await con.ExecuteAsync(sql);
}
}
答案 1 :(得分:3)
这是安全的,但在Execute
完成之前它会一直阻塞。访问Task.Result
等同于:
Task<int> task = Execute("...");
task.Wait(); // blocks until done
return 0 < task.Result;
如果您希望进一步推进await
链,可以Success
代替Task<bool>
。
请注意,根据当前SynchronizationContext
,可能存在死锁。如果您的SynchronizationContext
是单线程的,那么您对Task.Result
的调用最终会阻塞并等待Execute
完成,但Execute
正在等待您释放该线程,它可以继续。如果您使用的是GUI应用程序(默认情况下使用单线程SynchronizationContext)或ASP.NET,那么您是否要考虑添加ConfigureAwait(false)
以使Execute
运行在而不是线程池线程。