C#爲什麼多線程控制winform需要用委託?比如我新起了一個線程A,在A線程裏要對winform的list控件裏顯示數據,我需要用一個委託函數來實現。
因爲winform是主線程創建的,你用另外一個線程來調用它就可能會出現兩個線程同時訪問同一個資源的問題,這個時候很容易出現錯誤,比如A線程改變窗口的顏色爲紅色,B線程取窗口的顏色,如果這兩個線程正好碰到一起,可能A略先於B,那麼就是B取出來的紅色,如果略後於那麼就是原來的顏色,而這和CPU的繁忙度、時間片的輪轉是相關的,是一種隨機的情況,那麼B取出來的顏色就不可靠了,因此爲了避免這種狀況採用委託,B線程向A線程發出委託,由A線程來完成取色工作,那麼可以保證取色工作的穩定性,結果也可靠
如果你實在想通過另一個線程訪問winform,可以在窗口的構造函數中加入
Control.CheckForIllegalCrossThreadCalls = false;
這樣可以屏蔽這個錯誤,不過建議還是用委託
如果你實在想通過另一個線程訪問winform,可以在窗口的構造函數中加入
Control.CheckForIllegalCrossThreadCalls = false;
這樣可以屏蔽這個錯誤,不過建議還是用委託
這需要用到委託.
你先聲明一個委託,然後,把一個操作界面的函數託給他.
你的線程裏只要調用這個委託就可以了.
你先聲明一個委託,然後,把一個操作界面的函數託給他.
你的線程裏只要調用這個委託就可以了.
C#試寫一個多線程問題(委託,Invoke(),beginInvoke())
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
namespace _
{
public partial class Form1 : Form
{
public delegate void del(string str);
public delegate void del1(string str1);
Thread thread1,thread2;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.thread1 = new Thread(new ThreadStart(this.sa));
this.thread1.Start();
//MessageBox.Show(this,);
this.button1.Enabled = false;
//獲取當前的線程好
int thread1id = Thread.CurrentThread.GetHashCode();
string strThreadId = Convert.ToString(thread1id);
MessageBox.Show(this,strThreadId);
}
private void progressSet(string text)
{
progressBar1.Value = 0;
progressBar1.Maximum = 999999;
for (int i = 0; i < 999999; i++)
{
progressBar1.Value++;
}
progressBar1.Value = 0;
}
private void sa()
{
del pro = new del(progressSet);
this.Invoke(pro, new object[] { "hello" });
}
private void button2_Click(object sender, EventArgs e)
{
this.thread2 = new Thread(this.sa1);
thread2.Start();
this.button2.Enabled = false;
//獲取當前的線程好
int thread2id = Thread.CurrentThread.GetHashCode();
string strThreadId = Convert.ToString(thread2id);
MessageBox.Show(this, strThreadId);
}
private void sa1()
{
//其他操作
//比如將界面的TextBox內容設置一下
del1 mi1 = new del1(UpdateTextBox);
this.Invoke(mi1, new object[] { "我是一個文本框" });
}
//更新界面的方法
private void UpdateTextBox(string str)
{
//更新
this.textBox1.Text = str;
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
namespace _
{
public partial class Form1 : Form
{
public delegate void del(string str);
public delegate void del1(string str1);
Thread thread1,thread2;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.thread1 = new Thread(new ThreadStart(this.sa));
this.thread1.Start();
//MessageBox.Show(this,);
this.button1.Enabled = false;
//獲取當前的線程好
int thread1id = Thread.CurrentThread.GetHashCode();
string strThreadId = Convert.ToString(thread1id);
MessageBox.Show(this,strThreadId);
}
private void progressSet(string text)
{
progressBar1.Value = 0;
progressBar1.Maximum = 999999;
for (int i = 0; i < 999999; i++)
{
progressBar1.Value++;
}
progressBar1.Value = 0;
}
private void sa()
{
del pro = new del(progressSet);
this.Invoke(pro, new object[] { "hello" });
}
private void button2_Click(object sender, EventArgs e)
{
this.thread2 = new Thread(this.sa1);
thread2.Start();
this.button2.Enabled = false;
//獲取當前的線程好
int thread2id = Thread.CurrentThread.GetHashCode();
string strThreadId = Convert.ToString(thread2id);
MessageBox.Show(this, strThreadId);
}
private void sa1()
{
//其他操作
//比如將界面的TextBox內容設置一下
del1 mi1 = new del1(UpdateTextBox);
this.Invoke(mi1, new object[] { "我是一個文本框" });
}
//更新界面的方法
private void UpdateTextBox(string str)
{
//更新
this.textBox1.Text = str;
}
}
}