1. 程式人生 > 其它 >winform非UI執行緒操作UI控制元件方式

winform非UI執行緒操作UI控制元件方式

技術標籤:.NETwinform

序言

初學者遇到在非UI執行緒中操作控制元件會異常,這時會很蒙圈,包括我初學winform的時候也是一樣的,閒下來沒事的時候對該操作做了一個demo嘗試,接下來做一個解釋與記錄。

解決方案

直接附上程式碼:

using System;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        delegate void SetLabel(string
text); private void ChangeLabel4Text(string text) { label4.Text = text; } WindowsFormsSynchronizationContext context; SynchronizationContext context1; public Form1() { InitializeComponent(); context = SynchronizationContext.
Current
as WindowsFormsSynchronizationContext; context1 = SynchronizationContext.Current; System.Threading.Timer timerWindows = new System.Threading.Timer(TimerCallbackWindows, context, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1)); System.Threading.Timer timerBase =
new System.Threading.Timer(TimerCallbackBase, context1, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1)); } private void TimerCallbackWindows(object state) { // 不是從UI執行緒改變控制元件會異常的 //label3.Text = Guid.NewGuid().ToString(); context.Post(s => label1.Text = Guid.NewGuid().ToString() + "-WindowsFormsSynchronizationContext", state); Invoke(new MethodInvoker(() => { label3.Text = Guid.NewGuid().ToString() + "-MethodInvoker"; })); } private void TimerCallbackBase(object state) { context1.Post(s => label2.Text = Guid.NewGuid().ToString() + "-SynchronizationContext", state); // 使用系統自帶MethodInvoker委託 Invoke(new MethodInvoker(() => { label4.Text = Guid.NewGuid().ToString() + "-MethodInvoker"; })); Thread.Sleep(TimeSpan.FromMilliseconds(500)); // 自定義委託 Invoke(new SetLabel(ChangeLabel4Text), Guid.NewGuid().ToString() + "-Invoke"); // 採用Action方式 Invoke(new Action(() => { // TODO:操作UI控制元件 })); } } }

效果如下:
在這裡插入圖片描述

主流方式比較推薦使用Action