为什么WinForms/WPF控件不在内部使用Invoke?

Mat*_*ský 5 c# wpf concurrency winforms

我理解为什么GUI控件具有线程亲和力.

但是为什么控件不在内部使用它们的方法和属性中的调用?

现在你必须做这样的事情只是为了更新TextBox价值:

this.Invoke(new MethodInvoker(delegate()
{
    textBox.Text = "newValue";
}
Run Code Online (Sandbox Code Playgroud)

虽然使用就textBox.Text = "newValue";足以代表相同的逻辑.

所有必须做的就是改变textBox.Text逻辑(伪代码):

public string Text
{
    set
    {
        if(!this.InvokeRequired)
            // do the change logic
        else
            throw new BadThreadException();
    }
}
Run Code Online (Sandbox Code Playgroud)

对此:

public string Text
{
    set
    {
        if(!this.InvokeRequired)
            // do the change logic
        else
            this.Invoke(new MethodInvoker(delegate()
            {
                // do the change logic
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

吸气剂和方法也是如此.

我当然不打算删除Invoke/BeginInvoke,我只是问为什么控件不会自己进行必要的线程切换而不是抛出异常.

Anv*_*aka 9

我认为这样API可以强制开发人员做出明确的决定并避免无意的编程错误.以下是我可以立即提出的几个问题:

1.无意的线程阻塞.如果您写入属性,则调用线程必须阻塞,直到UI线程处理消息.如果调用线程拥有UI线程可能想要获取的资源,则会遇到难以调试的死锁(调用线程持有资源,等待消息由UI线程处理; UI线程等待直到资源被释放).

2.出乎意料的惊喜.如果我们将使写操作隐式异步,我们会遇到这样一种情况,即读者永远不要期望值始终是最新的.

3.业绩影响.如果您编写了一个隐式使用UI调度的密集算法,那么最终会导致性能非常差,您可以自由地责怪框架开发人员.毕竟你编写了应该在O(n)中运行的排序,但由于某种原因,它需要很长时间才能完成.