1. 程式人生 > >c#中 線程訪問控件的解決方法 可直接調用此方法

c#中 線程訪問控件的解決方法 可直接調用此方法

個人理解 調用 sys ext app tar 執行 csharp back

問題

由於在初學c#的時候 使用了 線程委托去執行函數,是為了不讓軟件窗體假死。所以使用下方代碼:

Thread th = new Thread(Getform); //創建線程
th.Start();

在使用前需要引入 : using System.Threading;

但是,在Getform 函數中,我調用了修改窗體控件內容的命令。

textbox.text="假";

直接報錯了。

線程間操作無效: 從不是創建控件“textbox”的線程訪問它

好吧。查找資料,進行查看解決方法、

解決方法:

1、直接忽略線程權限的檢查。

public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}

我們加入了這段代碼:Control.CheckForIllegalCrossThreadCalls = false; //忽略線程權限檢查

個人理解:這樣直接忽略也可能有其他的問題,所以大家都是不推薦的,但是也確實在某些時候可以使用,畢竟 方便。。。

2、使用委托進行安全的修改,使用delegate和invoke來從其他線程中控制控件信息(網絡復制說明)

網絡上的代碼 直接復制在C#中查看更加明顯

public partial class Form1 : Form 
{ 
private delegate void FlushClient();//代理 
public Form1() 
{ 
InitializeComponent(); 
} 
private void Form1_Load(object sender, EventArgs e) 
{ 
Thread thread = new Thread(CrossThreadFlush); 

thread.IsBackground=true; 
thread.Start(); 
} 

private void CrossThreadFlush() 
{ 
//將代理綁定到方法 
FlushClient fc = new FlushClient(ThreadFuntion); 
this.BeginInvoke(fc);//調用代理 
} 
private void ThreadFuntion() 
{ 
while (true) 
{ 
this.textBox1.Text = DateTime.Now.ToString(); 
Thread.Sleep(1000); 
} 
} 
} 

看起來還是相對很簡單的,只是這種會讓窗口無響應,因為在無限的刷新窗口,但是。會不會有更好的處理方法呢。

最終的解決方法:

private void button1_Click(object sender, EventArgs e)
        {
            var th = new Thread(() =>
            {
                //label1.Enabled = false;
                label1.CrossThreadCalls(() => { label1.Enabled = !label1.Enabled; });
                WriteMessage(DateTime.Now.ToString());
            });
            th.IsBackground = true;
            th.Start();
        }


        public void WriteMessage(string msg)
        {
            label1.CrossThreadCalls(() =>
            {
                label1.Text = msg;
            });
        }

在使用前,我們新建一個類。

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

namespace WindowsFormsApplication1
{
   public static class Class1
    {
       /// <summary>
       /// 跨線程訪問控件 在控件上執行委托
       /// </summary>
       /// <param name="ctl">控件</param>
       /// <param name="del">執行的委托</param>
       public static void CrossThreadCalls(this Control ctl, ThreadStart del)
       {
           if (del == null) return;
           if (ctl.InvokeRequired)
               ctl.Invoke(del, null);
           else
               del();
       }
    }
}

  

最終,我們得出了這種解決方法。還算是不錯。

我只是在學習過程中記錄,歡迎大家探討

原文地址:http://www.lazyw.org/weituo.html

c#中 線程訪問控件的解決方法 可直接調用此方法