如何在异步方法的单元测试中测试ConfigureAwait(false)?

Cha*_*ion 7 c# unit-testing deadlock async-await

我有一些异步库方法,重要的ConfigureAwait(false)是"一直使用".我想编写一个NUnit测试来验证是这样的.我怎样才能做到这一点?我想我必须以某种方式用自定义实现劫持同步上下文?

Tho*_*que 4

我认为这是不可能的。您可以创建自定义同步上下文(请参阅下面删除的答案),但它只会检查第一个等待的调用。如果第一个等待的调用称为 use ConfigureAwait(false),则延续将在不同的线程上运行,该线程不会有 a SynchronizationContext,因此无法检查后续异步调用ConfigureAwait(false)是否使用。


事实上,自定义同步上下文似乎是唯一的方法。这是一个可能的实现:

class TestSynchronizationContext : SynchronizationContext
{
    public bool PostCalled { get; private set; }

    public override void Post(SendOrPostCallback d, object state)
    {
        PostCalled = true;
        base.Post(d, state);
    }

    public void Reset()
    {
        PostCalled = false;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以像这样编写测试:

[Test]
public void TestFoo()
{
    var context = new TestSynchronizationContext();
    SynchronizationContext.SetSynchronizationContext(context);
    FooAsync().Wait();
    Assert.IsFalse(context.PostCalled);
}
Run Code Online (Sandbox Code Playgroud)

如果PostCalled为 true,则意味着调用了SynchronizationContexts方法,如果使用的话 Post,则不应发生这种情况。ConfigureAwait(false)