NUnit 将 CallContext 中的 ILogicalThreadAffinative 项复制到新线程
我遇到了 NUnit 和 CallContext(使用 C#)的问题,其中 NUnit 在创建新线程时复制现有调用上下文中扩展 ILogicalThreadAffinative 的任何内容。例如,在以下示例中,新创建的线程中始终会引发异常:
[Test]
public void TestCopiedCallContext()
{
Foo f = new Foo();
f.a = 1;
CallContext.SetData("Test", f);
new Thread(new ThreadStart(delegate()
{
if (CallContext.GetData("Test") != null)
{
throw new Exception("Bad!");
}
})).Start();
Thread.Sleep(500);
}
class Foo : ILogicalThreadAffinative
{
public int a;
}
如果 Foo 不扩展 ILogicalThreadAffinative,则测试通过。我正在使用 .NET 2.0(由于其他限制,我们无法使用较新版本的 .NET)。我还尝试使用最新版本的 NUnit 中提供的 Requires* 属性,但没有成功。有谁知道如何关闭这种行为?
I've run into an issue with NUnit and CallContext (using C#) where NUnit is copying the anything in the existing call context that extends ILogicalThreadAffinative when a new thread is created. For example, in the following example an exception is always thrown in the newly-created thread:
[Test]
public void TestCopiedCallContext()
{
Foo f = new Foo();
f.a = 1;
CallContext.SetData("Test", f);
new Thread(new ThreadStart(delegate()
{
if (CallContext.GetData("Test") != null)
{
throw new Exception("Bad!");
}
})).Start();
Thread.Sleep(500);
}
class Foo : ILogicalThreadAffinative
{
public int a;
}
If Foo doesn't extend ILogicalThreadAffinative then the test passes. I'm using .NET 2.0 (due to other restrictions we cannot use newer versions of .NET). I've also tried using the Requires* attributes available in the latest version of NUnit but with no success. Does anyone know how to turn this behavior off?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不相信你能做你想做的事。有人建议将代码放入测试运行者可以访问的程序集中。
您可能知道一篇博客文章,其中描述了问题是。
执行多线程的单元测试代码可能具有挑战性,我倾向于隔离线程并包装静态对象。
如果是我,我想我会尝试通过将调用上下文包装在 CallContextWrapper 类中来隔离 CallContext.SetData 和 CallContext.GetData:ICallContextWrapper。
我将测试我的代码是否使用 contextWrapper.SetData("Test", f) 并完成它;
我相信编写 CallContext 的人测试了它接收某些数据并将其传输到新线程的能力。 IMO CallContext 是应该已经经过测试的框架代码,因此您只需隔离代码对 CallContext 的依赖即可。
I dont beleive that you can do what you are attempting to do. One person has suggested putting the code into an assembly where the test runner has access to it.
There is a blog post that you probably know about, that describes what the issue is.
Unit testing code that does multithreading can be challenging and I tend to isolate threads and wrap static objects.
If it were me, I think that I would try to isolate CallContext.SetData and CallContext.GetData by wrapping call context in a class CallContextWrapper : ICallContextWrapper.
The I would test that my code uses contextWrapper.SetData("Test", f) and be done with it;
I would trust that whoever wrote CallContext tested it's ability to take in some data and transfer it to a new thread. IMO CallContext is framework code that should have already been tested so you just need to isolate your code's dependency on CallContext.