在VS 2005 中考虑到线程的安全性,不允许跨线程调用控件! 为了解决这一问题
1. 将Control 的 CheckForIllegalCrossThreadCalls 属性设置为假, 不去捕获错误线程的调用,但这种做法是不安全的!
2.使用委托异步调用
见代码:
using
System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace TabSelect
... {
class MyThread
...{
public delegate void SetLabelText(string text); //定义委托
Control control;
Thread thread;
ThreadStart start;
int num2;
构造方法,初始化线程,以及要改变属性的控件#region 构造方法,初始化线程,以及要改变属性的控件
public MyThread(Control control,int num)
...{
this.control = control;
start = new ThreadStart(BuildNum2); //订阅线程要执行的代码
this.num2 = num;
thread = new Thread(start);
thread.Start();
}
#endregion
线程中需要执行的方法 通过设置Control 属性,指示是否捕获错误线程的调用#region 线程中需要执行的方法 通过设置Control 属性,指示是否捕获错误线程的调用
public void BuildNum()
...{
Random random = new Random(num2);
Control.CheckForIllegalCrossThreadCalls = false;
do
...{
int num = random.Next(0, 10);
control.Text = num.ToString();
Thread.Sleep(100);
} while (true);
}
#endregion
方法二,使用委托异步调用#region 方法二,使用委托异步调用
public void BuildNum2()
...{
Random myRand = new Random(num2);
while (true)
...{
SetText(myRand.Next(0, 10).ToString());
Thread.Sleep(100);
}
}
#endregion
改变UI 线程的控件属性#region 改变UI 线程的控件属性
public void SetText(string str)
...{
if (control.InvokeRequired)
...{
SetLabelText setLableText = new SetLabelText(SetText);
control.Invoke(setLableText, new object[] ...{ str});
}
else
...{
control.Text = str;
}
}
#endregion
public void Kill()
...{
thread.Abort();
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace TabSelect
... {
class MyThread
...{
public delegate void SetLabelText(string text); //定义委托
Control control;
Thread thread;
ThreadStart start;
int num2;
构造方法,初始化线程,以及要改变属性的控件#region 构造方法,初始化线程,以及要改变属性的控件
public MyThread(Control control,int num)
...{
this.control = control;
start = new ThreadStart(BuildNum2); //订阅线程要执行的代码
this.num2 = num;
thread = new Thread(start);
thread.Start();
}
#endregion
线程中需要执行的方法 通过设置Control 属性,指示是否捕获错误线程的调用#region 线程中需要执行的方法 通过设置Control 属性,指示是否捕获错误线程的调用
public void BuildNum()
...{
Random random = new Random(num2);
Control.CheckForIllegalCrossThreadCalls = false;
do
...{
int num = random.Next(0, 10);
control.Text = num.ToString();
Thread.Sleep(100);
} while (true);
}
#endregion
方法二,使用委托异步调用#region 方法二,使用委托异步调用
public void BuildNum2()
...{
Random myRand = new Random(num2);
while (true)
...{
SetText(myRand.Next(0, 10).ToString());
Thread.Sleep(100);
}
}
#endregion
改变UI 线程的控件属性#region 改变UI 线程的控件属性
public void SetText(string str)
...{
if (control.InvokeRequired)
...{
SetLabelText setLableText = new SetLabelText(SetText);
control.Invoke(setLableText, new object[] ...{ str});
}
else
...{
control.Text = str;
}
}
#endregion
public void Kill()
...{
thread.Abort();
}
}
}
界面
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 TabSelect
... {
public partial class Form2 : Form
...{
Point myPoint;
private bool isMouseDown;
private bool isStart = true;
MyThread m;
MyThread m2;
MyThread m3;
public Form2()
...{
InitializeComponent();
}
private void label4_Click(object sender, EventArgs e)
...{
this.Close();
Application.Exit();
}
private void Form2_MouseDown(object sender, MouseEventArgs e)
...{
if (e.Button == MouseButtons.Left)
...{
myPoint = new Point(-e.X,-e.Y);
isMouseDown = true;
}
}
private void Form2_MouseMove(object sender, MouseEventArgs e)
...{
if (isMouseDown == true)
...{
Point newPoint = Control.MousePosition;
newPoint.Offset( myPoint.X,myPoint.Y);
this.Location = newPoint;
}
}
private void Form2_MouseUp(object sender, MouseEventArgs e)
...{
if (e.Button == MouseButtons.Left)
...{
isMouseDown = false;
}
}
private void Form2_Load(object sender, EventArgs e)
...{
}
private void timer1_Tick(object sender, EventArgs e)
...{
Random myRandom = new Random();
label1.Text = myRandom.Next(0, 10).ToString();
}
private void button1_Click(object sender, EventArgs e)
...{
if (isStart == true)
...{
m = new MyThread(label1,1000);
m2 = new MyThread(label2,1111);
m3 = new MyThread(label3, 2222);
isStart = false;
button1.Text = "结束";
}
else
...{
m.Kill();
m2.Kill();
m3.Kill();
isStart = true;
button1.Text = "开始";
}
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace TabSelect
... {
public partial class Form2 : Form
...{
Point myPoint;
private bool isMouseDown;
private bool isStart = true;
MyThread m;
MyThread m2;
MyThread m3;
public Form2()
...{
InitializeComponent();
}
private void label4_Click(object sender, EventArgs e)
...{
this.Close();
Application.Exit();
}
private void Form2_MouseDown(object sender, MouseEventArgs e)
...{
if (e.Button == MouseButtons.Left)
...{
myPoint = new Point(-e.X,-e.Y);
isMouseDown = true;
}
}
private void Form2_MouseMove(object sender, MouseEventArgs e)
...{
if (isMouseDown == true)
...{
Point newPoint = Control.MousePosition;
newPoint.Offset( myPoint.X,myPoint.Y);
this.Location = newPoint;
}
}
private void Form2_MouseUp(object sender, MouseEventArgs e)
...{
if (e.Button == MouseButtons.Left)
...{
isMouseDown = false;
}
}
private void Form2_Load(object sender, EventArgs e)
...{
}
private void timer1_Tick(object sender, EventArgs e)
...{
Random myRandom = new Random();
label1.Text = myRandom.Next(0, 10).ToString();
}
private void button1_Click(object sender, EventArgs e)
...{
if (isStart == true)
...{
m = new MyThread(label1,1000);
m2 = new MyThread(label2,1111);
m3 = new MyThread(label3, 2222);
isStart = false;
button1.Text = "结束";
}
else
...{
m.Kill();
m2.Kill();
m3.Kill();
isStart = true;
button1.Text = "开始";
}
}
}
}