在主线程上调用Application.DoEvents与ThreadPool中相同吗?

时间:2015-12-07 13:44:13

标签: .net unit-testing threadpool doevents

我们尝试自动测试一些旧的遗留代码。有一个打开,运行计时器和从端口读取数据的表单。 unittest打开表单,但是在Application.DoEvents开始处理windows消息队列的进程之前,计时器不会打勾。它是不同的,因为它是从unittest执行而Application.Run不是代码的一部分。

但我们不能通过Application.DoEvents阻止unittest线程,因为我们需要等待并通过断言检查数据。

class TodoApp extends React.Component {
  // ...
}

TodoApp = connect(
  // ...
)(TodoApp);

TodoApp = Relay.createContainer(TodoApp, {
  // ...
});

export default TodoApp;

但是这个片段并没有达到我的预期。它与从WinForm App执行表单不同?我可以从threadpool调用Application.DoEvents吗?

我真的不想修改遗留代码。我只需要对当前的解决方案进行单元测试。

1 个答案:

答案 0 :(得分:1)

执行此操作的最佳方法是使用Application.Run正常运行表单。完成测试后,关闭表单或调用该线程上的Application.Exit

DoEvents在当前线程上泵送事件。可以有多个UI线程。 DoEvents仅影响当前版本。

您的单元测试代码可能如下所示:

Form form = null;
var task = Task.Factory.StartNew(() => {
 form = new Form(); //Run ctor on UI thread.
 Application.Run(form);
}, LongRunning);

//Work with the form here.

form.Invoke(() => Application.Exit());
task.Wait();

这只是一个草图。缺少同步,我确信还有其他事情需要解决。

LongRunning确保GUI每次都在新线程上运行。这可以防止状态泄漏从测试到测试。

基本上,这是标准UI线程加工作线程模型。这里,单元测试线程是worker,需要创建UI线程。通常,UI线程将是Main线程,并且将创建工作线程。