如何在 MSTest 中使用 WaitHandler.WaitAll 而不会出现 STA 警告?
-
15-09-2020 - |
题
有没有办法进行单元测试 WaitHandle.WaitAll()
使用 Visual Studio 的内置单元测试解决方案时。当我尝试在 Visual Studio 中运行使用此函数的测试时,测试失败,并且在检查测试结果时显示以下错误:
WaitAll for multiple handles on a STA thread is not supported
我希望能够对使用进行单元测试 WaitAll()
因为越来越多的 API 代码库现在正在迁移到 IAsyncResult
模式而不是执行多线程操作的其他方式。
编辑
根据 Anthony 的建议,这里有一个简单的辅助方法,可用于在单元测试环境中调用此类代码:
public static void TestInMTAThread(ThreadStart info)
{
Thread t = new Thread(info);
t.SetApartmentState(ApartmentState.MTA);
t.Start();
t.Join();
}
解决方案
你可能有两个问题。第一个是你说的那个:你不能等待多个等待处理在STA线程(MSTEST线程公寓)。我们可以用手动创建的MTA线程修复它。
public static void OnMtaThread(Action action)
{
var thread = new Thread(new ThreadStart(action));
thread.SetApartmentState(ApartmentState.MTA);
thread.Start();
thread.Join();
}
.
环境也有一个最大等待句柄限制。在.NET 2.0中,它看起来很难编码为64.等待超过限制将生成一个生成的icotagcode。您可以使用扩展方法等待块中的所有等待处理。
public static void WaitAll<T>(this List<T> list, TimeSpan timeout)
where T : WaitHandle
{
var position = 0;
while (position <= list.Count)
{
var chunk = list.Skip(position).Take(MaxWaitHandles);
WaitHandle.WaitAll(chunk.ToArray(), timeout);
position += MaxWaitHandles;
}
}
.
,你将它们一起定居在一起(在您的测试中(在测试的行为或断言部分)
OnMtaThread(() => handles.WaitAll(Timespan.FromSeconds(10)));
. 其他提示
在 Visual Studio 2008 和 2010 你可以改变你的 .testsettings
文件以通过添加在 MTA 线程下运行测试 <ExecutionThread apartmentState="MTA" />
.
<Execution>
<ExecutionThread apartmentState="MTA" />
</Execution>
对于我的Visual Studio 2010只有以下配置进行了测试工作。
<Execution>
<ExecutionThread apartmentState="1" />
</Execution>
. 对于VS2008,与VS2010相比,指令略有不同。对于VS2008,编辑TestRunconfig文件,并将以下内容添加到TestRunconfiguration元素:
<ExecutionThread apartmentState="MTA" />
. 不隶属于 StackOverflow