Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 单元测试时如何处理在其他线程中引发的异常?_Multithreading_Visual Studio_Unit Testing_Exception - Fatal编程技术网

Multithreading 单元测试时如何处理在其他线程中引发的异常?

Multithreading 单元测试时如何处理在其他线程中引发的异常?,multithreading,visual-studio,unit-testing,exception,Multithreading,Visual Studio,Unit Testing,Exception,使用Visual Studio Team Test进行测试时,会捕获测试中未处理的异常并在结果中报告。所以我有点惊讶地看到测试宿主进程(VSTestHost.exe)崩溃并显示系统崩溃对话框 经过进一步调查,此崩溃是在另一个线程中引发的未经处理的异常(更直接地说,它是一个异步套接字回调)。事实上,类似这样的事情会使托管过程崩溃: [TestMethod] void Test() { new Thread(() => { throw new Exception(); }).Start

使用Visual Studio Team Test进行测试时,会捕获测试中未处理的异常并在结果中报告。所以我有点惊讶地看到测试宿主进程(VSTestHost.exe)崩溃并显示系统崩溃对话框

经过进一步调查,此崩溃是在另一个线程中引发的未经处理的异常(更直接地说,它是一个异步套接字回调)。事实上,类似这样的事情会使托管过程崩溃:

[TestMethod]
void Test()
{
    new Thread(() => { throw new Exception(); }).Start();
}
有什么建议我应该在那里做吗

  • 我是否应该接受它,说任何分发/签入的代码都应该至少测试一次,这样就很可能被捕获
  • 我是否应该尝试安装一个全局异常处理程序,并在每个分解方法中检查其状态
  • 或者可能已经有人在帮你了

您可以尝试设置
AppDomain.CurrentDomain.UnhandledException
,看看是否有效?我不知道它是如何与VS测试工具思想交互的。通常,我会尝试通过注入一个线程提供程序来避免在单元测试中启动线程,该线程提供程序在单元测试期间实际上并不提供线程,而是同步执行

当然,使用这种方法,您无法测试任何类型的潜在争用,也无法测试并行运行的两个实际代码路径,但有一个很好的理由可以证明,这样的测试并不是真正的单元测试

当您同时测试两个线程时,您需要一个线程提供程序,它在线程结束时捕获异常并将其报告为失败。

有几个想法:

  • 使用BackgroundWorker进行单元测试工作。BackgroundWorker将自动捕获未处理的异常,并在RunWorkerCompletedEventArgs的Error属性中报告它们。但是,在BackgroundWorker完成工作之前,您需要一种阻止单元测试线程的方法
  • 这个选项本身不是一个好的选择,甚至可能不适合您的测试目标。尽管如此,我还是想提一提。您可以通过使用返回到.NET 1.0和1.1中如何处理来自其他线程的未处理异常。在.NET2.0之前,线程中未处理的异常被悄悄地忽略。然而,在.NET2.0中,它们实际上会导致应用程序终止。legacyUnhandledExceptionPolicy设置允许您具有.NET 2.0之前的行为
您可以使用全局异常处理程序捕获AppDomain中所有未捕获的异常:

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new EventHandler(UnhandledExceptionHandler);

我认为对于其他线程抛出的异常也适用。

< P>我可以从C++的领域(如果知识可以翻译)说,在给定线程中抛出的任何异常只能在该线程<强>中被捕获<强>。如果主应用程序启动另外三个线程,那么您必须独立地从每个(现在是4个)线程捕获异常。没有办法在线程代码中实现“全局”异常处理程序。这与操作系统中线程(和进程)的实现方式有关


但正如我所说,我不知道这种逻辑与C#的关系有多密切,因为它运行在Java这样的虚拟机上。

在测试中有多个线程对我来说听起来不太统一。测试中的逻辑是否有什么规定必须有几个线程?真的吗


或者是有一些被测代码的协作者碰巧是多线程的(比如套接字)?如果是这样的话,您真的应该用某种测试双重(mock、stub或其他什么)来替换这些协作者。使用双重测试的另一个好处是,与真实的线程相比,您可以更轻松地控制它们的行为和响应。

当您显式地控制线程(并且不想测试实际的线程)时,这种方法很有效。但是,让我想到这个问题的代码使用了新的异步套接字实现(SocketAsyncEventArgs),它在我无法控制的内部线程池上运行委托。当一个异常实际上在另一个线程中抛出时,这是有效的。值得注意的是,否则(与测试在同一线程中的异常)不会达到AppDomain级别,因为VS测试主机会捕获每个测试方法的异常