C# WinForms跨线程更新 UI

与在Android中一样, 子线程中更新UI被认为是线程不安全的, 会抛出异常.

子线程返回UI线程中更新UI的一个方法为:

1, 捕获应用的UI线程的上下文;

2, 定义线程任务;

3, 定义线程任务中用于回调的进行UI更新的方法(接受一个object参数);

4, 开启线程;

Form1.cs
using System;
using System.Windows.Forms;
using System.Threading;
 
namespace WeChatRobot
{
    public partial class mainContainer : Form
    {
 
        // 用于返回UI线程更新UI的上下文
        private SynchronizationContext mSynchronizationContext = null;
        private Thread mSetQRCodeThread = null;
        private string mQrCodeSavePath = "D:\\Temp\\tmp.jpg";
 
        // 线程任务
        private void UpdateQRCodePost()
        {
            DateTime epoch = new DateTime(1970, 1, 1);
            var startTimeMillis = (long)(DateTime.UtcNow - epoch).TotalMilliseconds;
            while (true)
            {
                if (System.IO.File.Exists(mQrCodeSavePath))
                {
                    mSynchronizationContext.Post(setQRCodePicture, true);
                    break;
                }
                else if ((long)(DateTime.UtcNow - epoch).TotalMilliseconds - startTimeMillis > 15000)
                {
                    mSynchronizationContext.Post(setQRCodePicture, false);
                    break;
                }
                Thread.Sleep(1000);
            }
        }
 
        // 用于更新UI的回调方法, 注意方法签名, 有一个接受object的参数
        private void setQRCodePicture(object successOrNot)
        {
            if (true == (bool)successOrNot)
            {
                qrCodePictureBox.ImageLocation = mQrCodeSavePath;
                hintLabel.Text = "请用微信扫描上方二维码进行登陆!";
            }
            else
            {
                hintLabel.Text = "二维码生成失败! 请重启程序!";
                DialogResult result = MessageBox.Show("二维码生成失败! 请重启程序!", "WeChatRobot");
                if (DialogResult.OK == result)
                {
                    Environment.Exit(0);
                }
            }
        }
 
        public mainContainer()
        {
            InitializeComponent();
 
            // 捕获主线程上下文
            mSynchronizationContext = SynchronizationContext.Current;
 
            // 开启线程
            mSetQRCodeThread = new Thread(new ThreadStart(UpdateQRCodePost));
            mSetQRCodeThread.Start();
        }
 
        private void mainContainer_Load(object sender, EventArgs e)
        {
 
        }
 
        private void qrCodePictureBox_Click(object sender, EventArgs e)
        {
 
        }
 
        private void hintLabel_Click(object sender, EventArgs e)
        {
 
        }
 
        private void settingButton_Click(object sender, EventArgs e)
        {
 
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/seliote/p/9312996.html