Asp.net Microsoft Azure.NET SDK异步同步

Asp.net Microsoft Azure.NET SDK异步同步,asp.net,.net,azure,asynchronous,synchronizationcontext,Asp.net,.net,Azure,Asynchronous,Synchronizationcontext,我正在为我的ASP.NET应用程序使用Azure Blob存储SDKMicrosoft.WindowsAzure.Storage。我见过一些同步方法调用异步方法。他们使用Microsoft.WindowsAzure.Storage.Core.Util中名为RunWithoutSynchronizationContext的助手方法 代码基本上是这样做的 SynchronizationContext current = SynchronizationContext.Current; try

我正在为我的ASP.NET应用程序使用Azure Blob存储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开发人员常见的陷阱之一是。最常见的情况是,这是由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);
    }
}
public void Test\u SomeActionNoDeadlock()
{
var context=newmock
{
CallBase=true
};
SynchronizationContext.SetSynchronizationContext(context.Object);
尝试
{
验证(m=>
m、 Post(It.IsAny(),It.IsAny()),Times.Never);
验证(m=>
m、 发送(It.IsAny(),It.IsAny()),次。从不);
}
最后
{
SynchronizationContext.SetSynchronizationContext(空);
}
}
现在我们有了一种方法来保证ConfigureAwait(false)在整个SDK方法中都被使用,只要我们通过方法中的逻辑路径获得100%的测试覆盖率