我正在编写一个 C# .Net 4.5 库,用于执行常见的 sql 数据库操作(备份、恢复、执行脚本等)。我希望每个操作都具有同步和异步函数,因为控制台和 GUI 应用程序都将使用该库,但我不想到处重复代码。所以在我看来,我有两个选择:
-
编写在同步函数中完成工作的代码,然后将其包装在异步函数的任务中,如下所示:
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);
}
-
编写在异步函数中执行工作的代码,并使用 .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.
}
一种选择比另一种更好吗?这是最佳实践吗?或者还有其他(更好的)替代方案吗?
我知道使用 .Wait() 的一个警告是,异步函数中的所有等待语句都必须使用 .ConfigureAwait(false) 以避免死锁(正如这里所讨论的 https://stackoverflow.com/questions/9343594/how-to-call-asynchronous-method-from-synchronous-method-in-c),但由于我正在编写一个永远不需要访问 UI 或 WebContext 的库,所以我可以安全地这样做。
我还要指出的是,SQL 库通常还具有可以使用的同步和异步函数,因此,如果在同步函数中执行工作,我会调用它们的同步函数,如果在异步函数中执行工作,我会调用它们的同步函数。会调用他们的异步函数。
感谢您的想法/建议。
-- 编辑:我也发布了这个问题在 MSDN 论坛上 http://social.msdn.microsoft.com/Forums/en-US/async/thread/7bc69ba9-64b0-447e-b200-ca47c9fdce43尝试获得微软官方回应——
我希望每个操作都具有同步和异步函数,因为控制台和 GUI 应用程序都将使用该库,但我不想到处重复代码。
最好的答案是:不。
Stephen Toub 有两篇关于这个主题的优秀博客文章:
- 我应该为同步方法公开异步包装器吗? http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx
- 我应该为异步方法公开同步包装器吗? http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx
他建议将异步方法公开为异步,将同步方法公开为同步。如果您需要公开两者,则将公共功能封装在私有(同步)方法中,并复制异步/同步差异。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)