【发布时间】:2015-03-11 14:11:22
【问题描述】:
我正在创建一个允许用户做两件简单事情的报告生成器:
- 开始生成报告。
- 在生成过程中中止报告。
出于单元测试的目的,我已经隔离了业务逻辑。 abort 方法的单元测试包含以下代码:
reportGenerator.GenerateReport();
reportGenerator.Abort();
abort 方法只是设置一个私有字段来标记是否已调用 abort:
public void Abort()
{
aborted = true;
}
GenerateReport 内部启动了一个新线程,报告生成的核心在该线程上执行,沿途检查多个位置的中止标志。
我遇到的问题是我的单元测试甚至没有执行中止方法,直到之后 GenerateReport() 完成执行,因此中止标志只是被设置执行完成后。
我认为该问题与在单元测试的同一线程中调用 GenerateReport() 和 Abort() 有关。似乎如果我在单元测试代码中创建一个新线程,并从新线程调用 GenerateReport(),我将能够异步调用 abort 方法,但是必须在所有外部创建一个线程似乎很麻烦我的业务逻辑。
如果有人对我正在尝试做的事情的最佳方式有任何建议或答案,我们将不胜感激!
【问题讨论】:
-
您必须在不同的线程中运行一个或另一个。同一个线程不能中断自己!您可以将
GenerateReport()作为不同线程中的任务运行,也可以启动一个在延迟后调用Abort()的任务。但无论如何,如果你想测试这个功能,你需要有两个不同的线程来解决这个问题。\ -
可能是另一个线程没有看到对 abort 变量的更改(或者与检查的其他内容出现故障——这在 x86 上更有可能)。但是,如果没有显示 abort 变量检查的代码,很难说。通常,我建议使用 CancellationTokenSource 而不是这样的变量,因为您必须自己处理同步问题。
-
有一个通用的任务取消模式,涉及到它提供的
CancellationTokenSource和CancellationTokens。你可能应该使用它。
标签: c# multithreading unit-testing abort