C#報錯"線程間操作無效: 從不是創建控件“XXX”的線程訪問它"--解決示例


C# Winform程序中,使用線程對界面進行更新需要特殊處理,否則會出現異常“線程間操作無效: 從不是創建控件“taskView”的線程訪問它。”

在網文“http://www.cnblogs.com/smileberry/p/3912918.html”的知道下,我做了下面的例程,希望對大家有所幫助,如果注釋不夠的話請訪問原文。

例程是點擊按鈕后啟動線程更新一個標簽的文字,界面如下:

 

程序如下:

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

namespace ThreadCgGui
{
    public partial class Form1 : Form
    {
        // 定義委托類型
        delegate void SetTextCallback(String str);

        public Form1()
        {
            InitializeComponent();
        }

        // 點擊按鈕啟動線程
        private void button1_Click(object sender, EventArgs e)
        {
            Thread th = new Thread(threadProcSafe);
            th.Start();
        }

        // 線程主體方法
        private void threadProcSafe()
        {
            for (int i = 0; i < 1000; i++)
            {
                if (i % 2 == 0)
                {
                    this.setText("123456789");
                }
                else
                {
                    this.setText("一二三四五六七八九");
                }

                Thread.Sleep(1000);
            }
            
        }

        // 本方法是跨線程更新UI使用的主流方法,使用控件的Invoke/BeginInvoke方法,將委托轉到UI線程上調用,實現線程安全的更新
        // 本質上還是把線程中要提交的消息,通過控制句柄調用委托交到UI線程中處理
        public void setText(String str)
        {
            if (label1.InvokeRequired)
            {
                // 解決窗體關閉時出現“訪問已釋放句柄”異常
                while (label1.IsHandleCreated == false)
                {
                    if (label1.Disposing || label1.IsDisposed) return;
                }

                SetTextCallback d = new SetTextCallback(setText);
                label1.Invoke(d, new object[] { str });

            }
            else
            {
                label1.Text = str;
            }
           
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            // 徹底的退出
            System.Environment.Exit(0);
        }
    }

}

 

例程下載:

 http://files.cnblogs.com/files/xiandedanteng/ThreadCgGui20170626.zip


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM