dea*_*dog 16 c# asynchronous synchronous async-await .net-4.5
我正在编写一个C#.Net 4.5库,用于执行常见的SQL数据库操作(备份,恢复,执行脚本等).我希望每个操作都有同步和异步函数,因为这个库将由控制台和GUI应用程序使用,但我不想在任何地方重复代码.所以我看到它,我有两个选择:
编写在同步函数中执行工作的代码,然后将其包装在async函数的任务中,如下所示:
public void BackupDB(string server, string db)
{
// Do all of the work and long running operation here
}
public async Task BackupDBAsync(string server, string db)
{
await Task.Factory.StartNew(() => BackupDB(server, db)).ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)编写在异步函数中执行工作的代码,并使用.Wait()从同步函数中调用它:
public async Task BackupDBAsync(string server, string db)
{
// Do all of the work and long running operation here, asynchronously.
}
public void BackupDB(string server, string db)
{
BackupDBAsync(server, db).Wait(); // Execution will wait here until async function finishes completely.
}
Run Code Online (Sandbox Code Playgroud)一种选择比另一种更好吗?这是一个最佳实践吗?或者还有其他(更好的)替代方案吗?
我知道使用.Wait()的一个警告是async函数中的所有await语句都必须使用.ConfigureAwait(false)来避免死锁(如这里所讨论的),但是因为我正在编写一个永远不会存在的库需要访问UI或WebContext我可以安全地做到这一点.
我还要注意,SQL库通常也有可以使用的同步和异步函数,所以如果在同步函数中工作,我会调用它们的同步函数,如果在异步函数中工作,我会调用他们的异步功能.
赞赏的想法/建议.
- 编辑:我也在MSDN论坛上发布了这个问题,试图获得正式的MS回复 -
Ste*_*ary 12
我希望每个操作都有同步和异步函数,因为这个库将由控制台和GUI应用程序使用,但我不想在任何地方重复代码.
最好的答案是:不要.
Stephen Toub有两个关于这个主题的优秀博客文章:
他建议将异步方法公开为异步方法,将同步方法公开为同步方法.如果需要公开两者,则将常用功能封装在私有(同步)方法中,并复制异步/同步差异.