Sté*_*écy 5 .net multithreading nunit unit-testing c#-3.0
编写了一个扩展方法(在单独的线程上启动事件处理程序类时基于GUI更新?):
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我一直试图从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"));
}
Run Code Online (Sandbox Code Playgroud)
测试通过,但如果我在InvokeEx方法(而不是调用)中设置断点,我看到Control.InvokeRequired为false,导致直接调用func方法.
此外,现在测试失败,因为未设置结果.
另外,在逐步执行代码时,我看到func方法在另一个线程上执行(如预期的那样),而不是在主线程上执行.
也许是因为我执行单元测试后没有真正的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"));
}
Run Code Online (Sandbox Code Playgroud)
这现在完美无缺.
请注意,我必须为InvokeEx添加一个void方法的重载.
| 归档时间: |
|
| 查看次数: |
1857 次 |
| 最近记录: |