如何在没有STA警告的情况下在MSTest中使用WaitHandler.WaitAll?

Rob*_*obV 8 c# unit-testing mstest waithandle

WaitHandle.WaitAll()使用Visual Studio的内置单元测试解决方案时,有没有办法进行单元测试.当我尝试在Visual Studio中运行使用此函数的测试时,测试失败,并在检查测试结果时显示以下错误:

WaitAll for multiple handles on a STA thread is not supported
Run Code Online (Sandbox Code Playgroud)

我希望能够对单元测试的使用进行单元测试,WaitAll()因为越来越多的API代码库现在转移到一种IAsyncResult模式,而不是其他方式进行多线程操作.

编辑

根据Anthony的建议,这里有一个简单的辅助方法,可用于在单元测试环境中调用此类代码:

public static void TestInMTAThread(ThreadStart info)
{
    Thread t = new Thread(info);
    t.SetApartmentState(ApartmentState.MTA);
    t.Start();
    t.Join();
}
Run Code Online (Sandbox Code Playgroud)

Ant*_*ean 7

你可能有两个问题.第一个是您声明的那个:您不能等待STA线程中的多个等待句柄(MSTest线程单元状态).我们可以通过手动创建的MTA线程来解决这个问题.

public static void OnMtaThread(Action action)
{
    var thread = new Thread(new ThreadStart(action));
    thread.SetApartmentState(ApartmentState.MTA);
    thread.Start();
    thread.Join();
}
Run Code Online (Sandbox Code Playgroud)

环境还具有最大等待句柄限制.在.NET 2.0中,它似乎被硬编码为64.等待超过限制将产生一个NotSupportedException.您可以使用扩展方法等待块中的所有等待句柄.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

并且你在测试中将它们组合在一起(在测试的Act或Assert部分)

OnMtaThread(() => handles.WaitAll(Timespan.FromSeconds(10)));
Run Code Online (Sandbox Code Playgroud)