9

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();
}
4

4 回答 4

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();
}

环境也有最大等待句柄限制。在 .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;
    }
}

你会在你的测试中像这样将它们装配在一起(在测试的 Act 或 Assert 部分)

OnMtaThread(() => handles.WaitAll(Timespan.FromSeconds(10)));
于 2010-07-14T14:24:56.733 回答
2

Visual Studio 2008 和 2010中,您可以更改.testsettings文件以在 MTA 线程下运行测试,方法是添加<ExecutionThread apartmentState="MTA" />.

<Execution>
     <ExecutionThread apartmentState="MTA" />
</Execution>
于 2012-05-23T03:38:36.993 回答
0

对于我的 Visual Studio 2010,只有以下配置才能使测试工作。

<Execution>
     <ExecutionThread apartmentState="1" />
</Execution>
于 2012-08-28T13:33:55.297 回答
0

For VS2008 the instructions are slightly different compared to VS2010. For VS2008, edit the testrunconfig file, and add the following to the TestRunConfiguration element:

<ExecutionThread apartmentState="MTA" />
于 2014-06-04T14:51:06.807 回答