为什么是从不同的线程没有内置在.NET框架更新UI的格局? [英] Why is the pattern to update UI from a different thread not built into the .NET framework?

查看:186
本文介绍了为什么是从不同的线程没有内置在.NET框架更新UI的格局?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道为什么我的这个框架喜欢/不喜欢某某?问题是有点危险,但我想看看我错过了什么。

I know "why is my this framework like/not like xyz?" questions are a bit dangerous but I want to see what I'm missing.

在的WinForms,你不能更新从另一个线程的用户界面。大多数人使用<一个href="http://stackoverflow.com/questions/724972/updating-ui-from-a-different-thread/725135#725135">this模式:

In WinForms, you can't update the UI from another thread. Most people use this pattern:

private void EventHandler(object sender, DirtyEventArgs e)
{
    if (myControl.InvokeRequired)
        myControl.Invoke(new MethodInvoker(MethodToUpdateUI), e);
    else
        MethodToUpdateUI(e);
}

private void MethodToUpdateUI(object obj) 
{
    // Update UI
}

和更聪明还是这种模式的:

public static TResult SafeInvoke(this T isi, Func call) where T : ISynchronizeInvoke
{
    if (isi.InvokeRequired) { 
        IAsyncResult result = isi.BeginInvoke(call, new object[] { isi }); 
        object endResult = isi.EndInvoke(result); return (TResult)endResult; 
    }
    else
        return call(isi);
}

public static void SafeInvoke(this T isi, Action call) where T : ISynchronizeInvoke
{
    if (isi.InvokeRequired)
        isi.BeginInvoke(call, new object[] { isi });
    else
        call(isi);
}

无论哪个是虽然使用,每个人都有编写样板code来处理这个令人难以置信的通病。那么,为什么有.NET框架不被更新,以做到这一点的我们呢?难道的codeBase的这个区域被冻结?它是一个关注,这将打破向后兼容性?它是关于一个混乱问题时,一些code工作在版本N一种方式和版本不同的方式N + 1?

Regardless of which is used though, everyone has to write boilerplate code to handle this incredibly common problem. Why then, has the .NET Framework not been updated to do this for us? Is it that this area of the codebase is frozen? Is it a concern that it would break backwards compatibility? Is it a concern about the confusion when some code works one way in version N and a different way in version N+1?

推荐答案

我想这可能是有趣的,何况它为什么是,有摆在首位的UI线程。它是降低生产UI组件的成本,同时提高其正确性和鲁棒性。

I thought it might be interesting to mention why it is that there's a UI thread in the first place. It is to lower the cost of the production of UI components while increasing their correctness and robustness.

线程安全的基本问题是,私有状态的非原子更新可以被观察到上一个读数螺纹半成品如果写线程中途时完成的读取发生。

The basic problem of thread safety is that a non-atomic update of private state can be observed to be half-finished on a reading thread if the writing thread is halfway done when the read happens.

要实现线程安全还有很多事情可以做。

To achieve thread safety there are a number of things you can do.

1)明确锁定所有读取和写入。优点:最大限度地灵活;一切都可以在任何线程。缺点:期最大的痛苦;一切都已经被锁定所有的时间。锁可主张,这使得它们缓慢。这是很容易写死锁。这是很容易写code处理重入不良。等等。

1) Explicitly lock all reads and writes. Pros: maximally flexible; everything works on any thread. Cons: Maximally painful; everything has to be locked all the time. Locks can be contended, which makes them slow. It is very easy to write deadlocks. It is very easy to write code that handles re-entrancy poorly. And so on.

2)允许读取,并且只能在创建该对象的线程写入。可以有多个线程上的多个对象,但是,一旦一个物体上使用一个线程,这是可以用它的唯一线程。因此不会有读取,并同时在不同的线程写入,所以你不需要任何锁定。这是公寓模式,那就是UI组件绝大多数都建立期望模型。需要锁定的唯一的国家是一个国家通过在不同的线程的多个实例共享,这是pretty的容易做的。

2) Allow reads and writes only on the thread that created the object. You can have multiple objects on multiple threads, but once an object is used on a thread, that's the only thread that can use it. Therefore there will be no reads and writes on different threads simultaneously, so you don't need to lock anything. This is the "apartment" model, and it is the model that the vast majority of UI components are built to expect. The only state that needs to be locked is state shared by multiple instances on different threads, and that's pretty easy to do.

3)允许读取,只有在拥有线程写入,但允许一个线程明确交班所有权转让给其他当没有读取和写入的进展。这是租赁的模式,它是由Active Server Pages的回收脚本引擎模型。

3) Allow reads and writes only on the owning thread, but allow one thread to explicitly hand off ownership to another when there are no reads and writes in progress. This is the "rental" model, and it is the model used by Active Server Pages to recycle script engines.

由于UI组件绝大多数都写在单元模型的工作,这是痛苦的,难以使所有这些组件自由线程,你坚持不必做UI线程上的所有用户界面的工作。

Since the vast majority of UI components are written to work in the apartment model, and it is painful and difficult to make all those components free-threaded, you're stuck with having to do all UI work on the UI thread.

这篇关于为什么是从不同的线程没有内置在.NET框架更新UI的格局?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆