有没有办法进行单元测试 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" />
.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top