处理跨线程更新Winform UI控件

https://www.cnblogs.com/marshal-m/p/3201051.html

C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件的线程访问它”的异常。处理跨线程更新Winform UI控件常用的方法有4种:
1. 通过UI线程的SynchronizationContext的Post/Send方法更新;
2. 通过UI控件的Invoke/BeginInvoke方法更新;

3. 通过BackgroundWorker取代Thread执行异步操作;
4. 通过设置窗体属性,取消线程安全检查来避免"跨线程操作异常"(非线程安全,建议不使用)。

 

Send() 是简单的在当前线程上去调用委托来实现(同步调用)。也就是在子线程上直接调用UI线程执行,等UI线程执行完成后子线程才继续执行。
 Post() 是在线程池上去调用委托来实现(异步调用)。这是子线程会从线程池中找一个线程去调UI线程,子线程不等待UI线程的完成而直接执行自己下面的代码。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApp1
{
    public struct Item
    {
        public int id;
        public string name;
    };
    public partial class Form1 : Form
    {
        SynchronizationContext m_SyncContext = null;
        Thread demoThread;
        public Item item;
        public Form1()
        {
            InitializeComponent();
            m_SyncContext = SynchronizationContext.Current;
        }

        private void ThreadProcSafePost()
        {
            //...执行线程任务

            //在线程中更新UI(通过UI线程同步上下文m_SyncContext)

            item.id = 1;
            item.name = "abc";
            m_SyncContext.Post(SetTextSafePost, item);
            Thread.Sleep(3000);
            item.id = 2;
            item.name = "def";
            m_SyncContext.Post(SetTextSafePost, item);

            //...执行线程其他任务
        }
        private void SetTextSafePost(object item)
        {
            this.label1.Text = ((Item)item).name+ ((Item)item).id.ToString();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            demoThread = new Thread(new ThreadStart(this.ThreadProcSafePost));
            this.demoThread.Start();
        }
    }
}
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值