今日在写个Windows Form下多线程程序(纯属练习),发现线程的使用并不是那么回事,出现“线程间操作无效: 从不是创建控件“textBox1”的线程访问它”的错误,百思不得其解,而后到MSDN查了相关资料,才知道Windows Form下不能直接从工作线程去访问不是本线程创建的控件(VS2003是可以的或者设置Control.CheckForIllegalCrossThreadCalls==false),要通过更加安全的方法,即通过Controls的静态方法Invoke来执行一个委托,如:
void myThread()
{
if(textBox1.InvokeRequired || textBox2.InvokeRequired)
Invoke( new myDel(scoreChange));
}
整个程序如下:
public partial class Form1 : Form
{
static int scoreChina = 0, scoreKorea = 0;
static int timePass=0;
static bool gameOver=false;
delegate void myDel(); //声明1个委托
public void scoreChange() //线程想要完成的任务
{
Random rd = new Random();
if (!gameOver)
{
if (rd.Next(2) == 0)
{
scoreChina += rd.Next(1, 3);
textBox1.Text = scoreChina.ToString();
}
else
{
scoreKorea += rd.Next(1, 3);
textBox2.Text = scoreKorea.ToString();
}
if (scoreChina == scoreKorea)
textBox3.Text = "Game Playing! China draw with Korea";
else if (scoreChina > scoreKorea)
textBox3.Text = "Game Playing! China lead!";
else
textBox3.Text = "Game Playing! Korea lead!";
}
if (scoreChina == scoreKorea)
textBox3.Text = "Game Over! China draw with Korea";
else if (scoreChina > scoreKorea)
textBox3.Text = "Game Over! China beat Korea!";
else
textBox3.Text = "Game Over! China Lost!";
}
public Form1()
{
InitializeComponent();
textBox1.Text = scoreChina.ToString();
textBox2.Text = scoreKorea.ToString();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (timePass >= 30)
{
gameOver = true;
timer1.Stop();
return;
}
else
{
timePass++;
Thread threadScoreChange = new Thread(new ThreadStart(myThread)); //实例化1个线程,入口点为myThread
threadScoreChange.Start();
}
Text = timePass.ToString();
}
void myThread()
{
if(textBox1.InvokeRequired || textBox2.InvokeRequired)
Invoke( new myDel(scoreChange)); //通过Invoke执行委托,从而去执行线程想要完成的任务
}
private void button2_Click(object sender, EventArgs e)
{
Thread.Sleep(1000);
}
}