根据这个很棒的博客,即使使用async/await(只要使用.NET 4.5和Immutable data),我们也可以安全地从CallContext的LogicalContext设置/获取数据。
让我们看看下面的简单程序:
...
CallContext.LogicalSetData("id", "123");
var id1 = CallContext.LogicalGetData("id");
await Task.Delay(100);
var id2 = CallContext.LogicalGetData("id");
...
当它在标准控制台程序中运行时,一切都很好——id1和id2都包含值"123"。
但是,如果在NUnit方法中运行,则id2包含NULL,而id1的值为"123"。
它为什么不能在NUnit框架中工作?
当在NUnit的本地运行程序(GUI和控制台)下运行时,包含与您发布的代码片段类似的代码片段的测试的行为是正确的,即id1和id2都具有值"123",您可以通过运行下面的测试并检查GUI和控制台中的输出来重现它。
[Test]
public async Task DoSomething()
{
CallContext.LogicalSetData("id", "123");
var id1 = CallContext.LogicalGetData("id");
Console.WriteLine("ID1: " + id1);
await Task.Delay(100);
var id2 = CallContext.LogicalGetData("id");
Console.WriteLine("ID2: " + id2);
}
当您使用R#运行测试时,这很可能是导致这种错误行为的原因。
值得注意的是,即使测试是async void,在GUI和Console下的行为也是正确的。