美文网首页
C#中跨线程更新UI的方法总结

C#中跨线程更新UI的方法总结

作者: 村上春竹 | 来源:发表于2016-09-25 16:03 被阅读947次

在C#编程环境中,不允许在工作线程中直接对主线程(UI线程)中的控件进行更新操作。因此,稍微复杂一点的程序,跨线程更新UI界面是非常常见的。目前,一般有以下几种方法可以实现在工作线程对UI控件的更新:

  1. 通过UI线程的SynchronizationContext的Post/Send方法更新
  2. 通过UI控件的Invoke/BeginInvoke方法更新
  3. 通过BackgroundWorker取代Thread执行异步操作
  4. 通过取消线程安全检查来避免"跨线程操作异常"

1 通过UI线程的SynchronizationContext的Post/Send方法更新

使用线程上下文更新UI线程的步骤:
第一步:获取UI线程同步上下文(在窗体构造函数或FormLoad事件中
第二步:定义线程的主体方法
第三步:定义更新UI控件的方法

通过UI线程与工作线程的时序图可以看出整个更新的步骤:

整个过程中关键的是主线程的SynchronizationContext,SynchronizationContext在通讯中充当传输者的角色。在线程执行过程中,需要更新到UI控件上的数据不再直接更新,而是通过UI线程上下文的Post/Send方法,将数据以异步/同步消息的形式发送到UI线程的消息队列;UI线程收到该消息后,根据消息是异步消息还是同步消息来决定通过异步/同步的方式调用SetTextSafePost方法直接更新自己的控件了。在本质上,向UI线程发送的消息并是不简单数据,而是一条委托调用命令。

关于SynchronizationContext的详细介绍,可以参考这篇文章:利用SynchronizationContext.Current在线程间同步上下文

2. 通过UI控件的Invoke/BeginInvoke方法更新

通过UI控件的Inovke/BeginInvoke方法同样也可以实现更新,具体步骤如下:


这个方法是目前跨线程更新UI使用的主流方法,使用控件的Invoke/BegainInvoke方法,将委托转到UI线程上调用,实现线程安全的更新。原理与方法1类似,本质上还是把线程中要提交的消息,通过控件句柄调用委托交到UI线程中去处理。

3. 通过BackgroundWorker取代Thread执行异步操作

BackgroundWorker组件是.Net推出的一个组件,用来方便地进行跨线程的界面更新操作。以下引自MSDN:

BackgroundWorker 类允许您在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。

具体可参见MSDN的描述:BackgroundWorker

4. 通过取消线程安全检查来避免"跨线程操作异常"

将Control类的静态属性CheckForIllegalCrossThreadCalls为false,这种方式简单粗暴,但是因为取消了跨线程的检查,可能会引起一些异常问题,因此不推荐使用。

相关文章

  • C#中跨线程更新UI的方法总结

    在C#编程环境中,不允许在工作线程中直接对主线程(UI线程)中的控件进行更新操作。因此,稍微复杂一点的程序,跨线程...

  • 非主线程更新UI:Handler.post*方法

    学习心得 post*方法中的Runnable参数中的run代码会在主线程中执行 总结非主线程更新UI的4非方法:H...

  • .NET多线程(十二)WinForm

    本节主要内容 ** WinForm 跨线程更新UI ** 通过UI线程的SynchronizationContex...

  • Android 程序员学习 iOS —— 在线程间跳舞

    跨线程更新UI 在客户端开发的过程中,我们经常碰到的问题有可能就是 IO 请求完成后,在主线程中更新 UI 这件事...

  • Android多线程

    1.沿用java的子线程创建 2.在子线程中不能更新UI,那么在Android中更新UI的方法 runOnUiTh...

  • APP崩溃提示:This application is modi

    崩溃输出日志 崩溃原因 在子线程中更新UI导致主线程的视图布局出错 解决方法 把更新UI的操作放在主线程中执行 s...

  • 子线程更新UI的方法

    子线程中不能直接更新UI,如果直接更新的话会发生崩溃所以要在主线程中更新UI,总计三种回到主线程更新UI的方式 1...

  • iOS知识点总结一

    接《iOS知识点大总结一》 三十四、主线程操作UI(对UI进行更新只能在主线程进行) 解释:所谓的在主线程更新UI...

  • 总结1

    1.为什么子线程不能访问更新Ui在onCreate方法中创建了子线程并访问UI,没有崩溃,因为ViewRootIm...

  • 关于子线程更新UI那些事儿

    我们都知道子线程不能更新UI,但是测试的时候发现,onCreate方法中子线程是可以更新UI的,onResume就...

网友评论

      本文标题:C#中跨线程更新UI的方法总结

      本文链接:https://www.haomeiwen.com/subject/jfefyttx.html