【问题标题】:How do I use WaitHandler.WaitAll in MSTest without STA warnings?如何在没有 STA 警告的情况下在 MSTest 中使用 WaitHandler.WaitAll?
【发布时间】:2010-07-14 12:46:39
【问题描述】:

在使用 Visual Studio 的内置单元测试解决方案时,有没有办法对 WaitHandle.WaitAll() 进行单元测试。当我尝试在 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();
}

【问题讨论】:

  • Visual Studio 的哪个版本?
  • Visual Studio 2008,必要时可以选择迁移到 2010

标签: c# unit-testing mstest waithandle


【解决方案1】:

您可能有两个问题。第一个是您所说的:您不能等待多个等待句柄in an STA thread(MSTest 线程单元状态)。我们可以通过手动创建的 MTA 线程来解决这个问题。

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

环境也有一个maximum wait handle limit。在 .NET 2.0 中,它似乎被硬编码为 64。等待超过限制将产生 NotSupportedException。您可以使用extension 方法来等待块中的所有等待句柄。

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

【讨论】:

  • 在这种情况下,action 将等待所有句柄。我将更新我的答案以展示一个示例单元测试以及这一切如何组合在一起。
  • 所以它需要更改生产代码?不能只在单元测试中修复?
  • 哦,对不起...我认为前提是您正在您的测试中安装等待句柄来测试回调或线程等内容。
  • 哦,我还没有遇到这个问题...听起来您需要某种协作者来检查当前线程状态并在必要时执行OnMtaThread 操作。更好的是,发布一个带有您的上下文和错误的问题!
【解决方案2】:

Visual Studio 2008 & 2010 中,您可以通过添加&lt;ExecutionThread apartmentState="MTA" /&gt; 来更改.testsettings 文件以在MTA 线程下运行测试。

<Execution>
     <ExecutionThread apartmentState="MTA" />
</Execution>

【讨论】:

    【解决方案3】:

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

    <Execution>
         <ExecutionThread apartmentState="1" />
    </Execution>
    

    【讨论】:

      【解决方案4】:

      VS2008 的指令与 VS2010 相比略有不同。对于 VS2008,编辑 testrunco​​nfig 文件,并将以下内容添加到 TestRunConfiguration 元素:

      <ExecutionThread apartmentState="MTA" />
      

      【讨论】:

        猜你喜欢
        • 2018-02-01
        • 2021-11-22
        • 1970-01-01
        • 2019-07-30
        • 1970-01-01
        • 1970-01-01
        • 2017-10-29
        • 2019-05-14
        相关资源
        最近更新 更多