编写了一个扩展方法(基于 GUI update when starting event handler class on separate thread?):
public static class ControlExtensions
{
public static TResult InvokeEx<TControl, TResult> (this TControl control,
Func<TControl, TResult> func)
where TControl : Control
{
if (control.InvokeRequired)
return (TResult)control.Invoke (func, control);
return func (control);
}
}
我一直在尝试从 UI 线程和普通线程对这种方法进行单元测试,但似乎无法实现。
下面是单元测试代码:
[Test]
public void TestInvokeExWithMethodReturningResultOnOtherThread ()
{
// Prepare
string result = string.Empty;
var form = new Form ();
var thread = new Thread (() =>
{
result = form.InvokeEx (f => f.Text);
});
// Execute
thread.Start ();
thread.Join (1000);
// Verify
Assert.That (result, Is.EqualTo ("Some label"));
}
测试通过,但如果我在 中设置断点InvokeEx 方法(不是调用)我看到 Control.InvokeRequired 为假导致 功能 方法直接调用。
此外,现在测试失败了,因为 结果 未设置。
此外,在逐步执行代码时,我看到 功能 方法在另一个线程上执行(如预期的那样)而不是在主线程上执行。
也许是因为我在执行单元测试后没有真正的 UI 线程?我将如何实现这一目标以及所有消息传递?
最佳答案
我一直在尝试不同的东西,我想出了以下几点:
[Test]
public void TestInvokeExWithMethodReturningResultOnOtherThread ()
{
// Prepare
string result = string.Empty;
var form = new Form ();
var uiThread = new Thread (() => Application.Run (form));
uiThread.SetApartmentState (ApartmentState.STA);
uiThread.Start();
Thread.Sleep (100);
var thread = new Thread (() => result = form.InvokeEx (f => f.Text));
// Execute
thread.Start ();
thread.Join ();
form.InvokeEx (f => f.Close ());
uiThread.Join ();
// Verify
Assert.That (result, Is.EqualTo ("Some label"));
}
这现在工作得很好。
请注意,我必须为无效方法为 InvokeEx 添加重载。
关于.net - 如何在另一个线程上正确地对调用 UI 方法进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1362858/