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,我只是问为什么控件不会自己进行必要的线程切换而不是抛出异常.
我认为这样API可以强制开发人员做出明确的决定并避免无意的编程错误.以下是我可以立即提出的几个问题:
1.无意的线程阻塞.如果您写入属性,则调用线程必须阻塞,直到UI线程处理消息.如果调用线程拥有UI线程可能想要获取的资源,则会遇到难以调试的死锁(调用线程持有资源,等待消息由UI线程处理; UI线程等待直到资源被释放).
2.出乎意料的惊喜.如果我们将使写操作隐式异步,我们会遇到这样一种情况,即读者永远不要期望值始终是最新的.
3.业绩影响.如果您编写了一个隐式使用UI调度的密集算法,那么最终会导致性能非常差,您可以自由地责怪框架开发人员.毕竟你编写了应该在O(n)中运行的排序,但由于某种原因,它需要很长时间才能完成.