Asp.net Microsoft Azure.NET SDK异步同步
我正在为我的ASP.NET应用程序使用Azure Blob存储SDKAsp.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
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%的测试覆盖率