Can't复制'跨线程操作无效;单元测试中的错误——我不明白

本文关键字:错误 明白 操作 复制 线程 无效 Can 单元测试 | 更新日期: 2023-09-27 18:13:41

这是我的第一个Stack问题,所以如果我的格式或礼仪有点不妥,请提前道歉。

我最近一直在设置模式来处理"跨线程操作无效"的问题,当从一个单独的线程与WinForms控件交互时。

我认为建立一个单元测试来隔离这个并断言我的SynchronisationContext扩展修复了这个问题会很好,所以我创建了一个简单的测试表单,上面有一个按钮和一些名为"PerformClick()"的代码,从另一个线程复制这个问题:

    [STAThread]
    static void Main()
    {           
        using (TestForm form = new TestForm())
        {
            Thread t1 = new Thread(() => Application.Run(form));
            Thread t2 = new Thread(() => form.buttonStart.PerformClick());
            form.Activated += (sender, args) => t2.Start();
            t1.Start();
            Thread.Sleep(1000); //Prevents form from being disposed before 'click' can occur from other thread.
        }                       
    }

测试表单实际上是一个空表单,上面只有一个按钮。当我运行这段代码时,得到了预期的跨线程操作异常。

但是当我将代码放入NUnit测试中时,异常没有发生。下面是我的单元测试:

    [Test]
    public void PostToControl_AcrossThreads()
    {           
        //Notes: This code normally generates a cross-thread exception.
        //For some reason, when you run it in the scope of the unit test, the exception is not generated.
        using (TestForm form = new TestForm())
        {
            Thread t1 = new Thread(() => Application.Run(form));
            Thread t2 = new Thread(() => form.buttonStart.PerformClick());
            form.Activated += (sender, args) => t2.Start();
            t1.Start();
            Thread.Sleep(1000); //Prevents form from being disposed before 'click' can occur from other thread.
        }
    }

我意识到我不清楚为什么会发生这种情况,所以我把它扔给专家:-)

有谁能开导我一下吗?与本机运行表单相比,单元测试中发生的事情有什么不同?

Can't复制'跨线程操作无效;单元测试中的错误——我不明白

不要使用PerformClick()。例如form.buttonStart.Text = "This is my form";或改变位置等…

原因是PerformClick()方法只引发。net事件Click。但是跨线程操作的问题在于windows-message-loop。因此,如果你想要"do problem",你必须执行一些操作,这使用了windows-message-loop。

此行为由一个属性控制:Control。CheckForIllegalCrossThreadCalls

默认情况下,只有在附加了调试器时才为真,这就是您所看到的行为。

有谁能开导我一下吗?这个单位发生了什么变化与本机运行表单相比进行测试?

没有什么不同。

如果你需要检查Nunit上的异常,最好使用异常断言。否则,nunit将不会为您显示异常。

如果你不为异常做资产,至少放一个try catch块并记录异常,你也会在测试用例上得到相同的异常。