asp.net - Microsoft Azure .NET SDK 异步同步

标签 asp.net .net azure asynchronous synchronizationcontext

我正在为 ASP.NET 应用程序使用 Azure Blob Storage SDK Microsoft.WindowsAzure.Storage。我见过一些同步方法调用异步方法。他们使用来自 Microsoft.WindowsAzure.Storage.Core.Util 的名为 RunWithoutSynchronizationContext 的辅助方法。

代码基本上是做类似的事情

  SynchronizationContext current = SynchronizationContext.Current;
  try
  {
    SynchronizationContext.SetSynchronizationContext((SynchronizationContext) null);
    methodAsync().Wait();
  }
  finally
  {
    SynchronizationContext.SetSynchronizationContext(current);
  }

我只是想知道这是否是一种避免 .NET Framework 阻塞异步代码时出现死锁的方法?如果不是,那么这个方法的目的是什么?

最佳答案

使用 .Net TPL 进行异步开发时,API 开发人员常见的陷阱之一是 deadlocks 。最常见的是,这是由 SDK 使用者以同步方式使用异步 SDK 引起的。

您可以使用ConfigureAwait(false)来避免死锁。在等待任务之前调用此例程将导致它忽略 SynchronizationContext。

var temp = await methodAsync().ConfigureAwait(false);

但是,您需要在整个 SDK 中放置 ConfigureAwait(false) 调用,而且很容易忘记。

因此,关键是了解 SynchronizationContext 的工作原理。无论何时使用它,都会调用它的 Send 或 Post 方法。 因此,我们需要做的就是确保这些方法永远不会被调用:

public void Test_SomeActionNoDeadlock()
{
    var context = new Mock<SynchronizationContext>
    {
        CallBase = true
    };
    SynchronizationContext.SetSynchronizationContext(context.Object);
    try
    {
        context.Verify(m => 
           m.Post(It.IsAny<SendOrPostCallback>(), It.IsAny<object>()), Times.Never);
        context.Verify(m => 
           m.Send(It.IsAny<SendOrPostCallback>(), It.IsAny<object>()), Times.Never);
    }
    finally
    {
        SynchronizationContext.SetSynchronizationContext(null);
    }
}

现在我们有办法保证在整个 SDK 方法中使用了ConfigureAwait(false),只要我们通过方法中的逻辑路径获得 100% 的测试覆盖率即可。

关于asp.net - Microsoft Azure .NET SDK 异步同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50379836/

相关文章:

Azure 门户中的 Azure 应用程序配置错误,无法添加配置

c# - 我应该如何在 Web API Controller 方法中返回数据?

c# - 将数据集导出到 asp.net c# 中的 excel 表

c# - 为什么在函数返回值后执行 C# 上整数的增量?

c# - 关于重构正则表达式字符类减法的建议

azure - 如何访问 Azure 数据工厂中 "Lookup Activity"上的输出?

python - Azure 批处理池 : How do I use a custom VM Image via Python?

javascript - 在新选项卡中打开后更改 html 链接的文本颜色?

.net - 如何知道我的 Asp.Net 应用程序在哪个 IIS 版本下运行?

.net - 无法为Dotnet核心Web应用程序从Docker文件构建Docker镜像