Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASPNet实体框架6-EF6,在同一工作单元中混合异步和同步_C#_Async Await_Entity Framework 6 - Fatal编程技术网

C# ASPNet实体框架6-EF6,在同一工作单元中混合异步和同步

C# ASPNet实体框架6-EF6,在同一工作单元中混合异步和同步,c#,async-await,entity-framework-6,C#,Async Await,Entity Framework 6,我今天遇到了几行代码,归结起来,它们相当于: using (var db = new AppDbContext()) { var foo = await db.Foos .Where(m => m.Name == "BuzzBaz" ) .FirstAsync(); foo.Name = "Quxx"; db.SaveChanges(); } 请注意,select查询是async,但对SaveChanges()的调用不是。它是同步

我今天遇到了几行代码,归结起来,它们相当于:

using (var db = new AppDbContext())
{
    var foo = await db.Foos
        .Where(m => m.Name == "BuzzBaz" )
        .FirstAsync();

    foo.Name = "Quxx";
    db.SaveChanges();
}
请注意,select查询是
async
,但对SaveChanges()的调用不是。它是同步的

这可能会产生任何问题吗?我应该重构它以使用
db.saveChangesSync()吗一切都好吗?或者干脆调用
First()
而不是
FirstAsync()
?或者它是无害的,可能对整个系统性能有一些好处

我找到一些文档,让我觉得完全删除
async
可能是一个不错的选择

在大多数应用程序中,使用异步将没有明显的好处,甚至可能是有害的。在提交之前,请使用测试、评测和常识来衡量特定场景中异步的影响

您的代码实际上是“正确的”,这意味着它没有根本缺陷

让我们分析一下发生了什么,以及我的2美分:

  • 在对db进行查询时(即
    FirstAsync
    ),使用
    wait
    意味着指令将按顺序执行,但线程不会被阻塞(异步调用),并且可以用于其他事情。这可能是一件好事,如果这是一个服务器应用程序,您可能希望您的线程能够在等待DB响应时处理其他请求

  • 但是,使用非异步
    SaveChanges
    将阻塞线程。这本身不是一个错误,但由于它也是db上的一个I/O操作,它可能会阻塞线程一段很长的时间。如果您在这里也使用异步版本等待
,它看起来确实更“一致”

这是个问题吗?视情况而定。你的应用程序被大量使用了吗?您的用户在重负载时是否遇到一些低反应性?在这种情况下,在保存时使用异步可能是一种潜在的改进

否则,正如链接的MSDN文章所建议的,在你知道它有影响之前,我的建议是不要太担心

混合使用本身不是问题

就我个人而言,我也会选择异步SaveChanges,以保持一致性,并设想DB写入是一些可能很慢的I/O操作


如果是桌面应用程序,只需确保不阻塞UI线程。

< P>除了编码一致性外,这是非常重要的-考虑以下内容:

  • 这是DAL图书馆吗?您确定谁将使用它吗?您确定代码的可重用性永远不会成为一个问题吗
  • 如果答案是可能的,那么坚持异步使用。在保存过程中,前端UI将被阻止,使其无响应。Web API利用IO线程实现更好的线程管理:

    如果它是一个库,请确保对所有异步函数调用使用
    ConfigureAwait(false)

  • 即使使用wait,调用也是异步的,就拓片在另一个线程上运行而言,而原始线程正在等待。大多数情况下,这是可以忽略不计的性能,但为什么不呢

  • 我通常使所有内容都异步,如果需要同步实现,我更喜欢使用同步版本复制代码。

    使用
    wait
    意味着语句将异步执行,执行流将返回给调用方。线程是否被阻塞取决于调用方。@PauloMorgado我不确定使用什么词,但为了让其他读者清楚:
    async Task MainFunction(){Console.WriteLine(“before”);wait Foo();Console.WriteLine(“after”)}
    async Task Foo(){//在几秒钟内进行长时间的处理…然后:Console.WriteLine(“processed!”):}
    将可靠地生成输出:“before”、“processed!”、“after”。在我看来,执行流非常“同步”,这就是
    等待的
    所做的(使异步调用看起来与执行流同步).你不是把顺序和同步混淆了吗?@PauloMorgado很可能!谢谢你的话,我会编辑我的答案的