該執行個體功能為“多線程控制UI控件”,線程函數實作自動加1。界面如下:
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;
namespace treadTest
{
//定義委托
public delegate void ListBoxDelegate();
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//委托處理方法(關聯與ListBoxDelegate)
private void ListBox()
if (!listBox1.InvokeRequired)//如果在UI主線程操作ListBox,
{
listBox1.Items.Add(++CommonData.num);//則直接進行控件操作,“與UI主線程相關聯”
listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1];
}
else//如果是在另一線程操作ListBox,則啟用委托
listBox1.Invoke(new ListBoxDelegate(listShow));
//定義對UI主線程控件的操作,“與AddAuto相關聯”。
private void listShow()
listBox1.Items.Add(CommonData.num);
listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1];
//定義線程函數
private void AddAuto()
while (CommonData.Flag == 0)
CommonData.num++;
Thread.Sleep(1000);
ListBox();//不能直接控制UI上的控件,是以用該方法選擇使用委托
//在click事件中啟動多線程
private void btnStart_Click(object sender, EventArgs e)
//線程标志置0,表示開啟線程
CommonData.Flag = 0;
//定義 ThreadStart的委托類型的參數,并使該委托指向線程函數
ListBoxDelegate mycn = new ListBoxDelegate(AddAuto);
//執行個體化線程
Thread insertTxt = new Thread(new ThreadStart(mycn));
//啟動線程
insertTxt.Start();
private void btnAbort_Click(object sender, EventArgs e)
CommonData.Flag = 1;
private void btnCtrlMain_Click(object sender, EventArgs e)
ListBox();
private void btnReset_Click(object sender, EventArgs e)
CommonData.num = 0;
private void btnClear_Click(object sender, EventArgs e)
listBox1.Items.Clear();
private void btnQuit_Click(object sender, EventArgs e)
Application.Exit();
}
//全局變量解決方案
public class CommonData
private static int _Flag = 0;
private static int _num = 0;
public static int Flag
get { return _Flag; }
set { _Flag = value; }
public static int num
get { return _num; }
set { _num = value; }
}
總結:
要使用多線程控制UI控件,必須用委托實作。調用控件的Invoke方法(Invoke方法的參數是一個委托類型的參數)。
實作步驟:
1.聲明委托。
2.聲明委托處理函數(判斷是主線程控制UI控件,還是Invoke(多線程)控制UI控件)。
3.聲明一個線程執行個體,将線程函數的委托傳入ThreadStart()。
4.開啟該線程。
5.定義該線程函數,欲控制UI控件,則調用第2步的委托處理函數,他将自己判斷選擇用Invoke。
6.定義Invoke需要調用的函數(如本例的listShow函數)
//*********************************************************************************************************************************
在上例中,隻是完成了多線程控制主線程控件的功能,如果能手動和自動同時通路全局變量時,就有可能出現線程不同步的問題。以下主要利用lock線程鎖來修改解決方案,使線程同步,注意代碼帶動的地方。
listBox1.Items.Add(CommonData.plus());//則直接進行控件操作,“與UI主線程相關聯”
listBox1.Items.Add(CommonData.plus());
public static int plus()
lock (new object())
return _num++;
本文轉自黃聰部落格園部落格,原文連結:http://www.cnblogs.com/huangcong/archive/2010/03/26/1697090.html,如需轉載請自行聯系原作者