您的位置:首页 > 编程语言 > C#

C# 多线程控制控件实例(例程简单,注释详细)

2009-05-02 11:15 561 查看
该实例功能为“多线程控制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线程锁来修改解决方案,使线程同步,注意代码带动的地方。

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.plus());//则直接进行控件操作,“与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.plus());

listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1];

}

//定义线程函数

private void AddAuto()

{

while (CommonData.Flag == 0)

{

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 plus()

{

lock (new object())

{

return _num++;

}

}

public static int Flag

{

get { return _Flag; }

set { _Flag = value; }

}

public static int num

{

get { return _num; }

set { _num = value; }

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: