1,Windows窗体控件不是线程安全的,如果多个线程操控WindowGUI组件,结果可能不正确。为了保证线程以线程安全的方式操控GUI组件,与GUI组件的所有交互都要由用户界面线程(UI线程)来执行,即创建和维护GUI的线程。Control类提供Invoke方法可以帮助这个过程。
2,Form1设计窗体:
3,Form1.cs 代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private Class1 letter1; private Class1 letter2; private Class1 letter3; private void Form1_Load(object sender, EventArgs e) { letter1 = new Class1(label1); Thread firstThread = new Thread(new ThreadStart(letter1.GenerateRandomCharacters)); firstThread.Name = "Thread 1"; firstThread.Start(); letter2 = new Class1(label2); Thread secondThread = new Thread(new ThreadStart(letter2.GenerateRandomCharacters)); secondThread.Name = "Thread 2"; secondThread.Start(); letter3 = new Class1(label3); Thread thirdThread = new Thread(new ThreadStart(letter3.GenerateRandomCharacters)); thirdThread.Name = "Thread 3"; thirdThread.Start(); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { System.Environment.Exit(System.Environment.ExitCode); } private void threadCheckBox_CheckedChanged(object sender, EventArgs e) { if (sender == checkBox1) letter1.Toggle(); else if (sender == checkBox2) letter2.Toggle(); else if (sender == checkBox3) letter3.Toggle(); } } }
3,Class1.cs 代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Windows.Forms; using System.Drawing; namespace WindowsFormsApplication1 { class Class1 { private static Random generator = new Random(); private bool suspended = false; private Label output; private string threadName; public Class1(Label label) { output = label; } private delegate void DisplayDelegate(char displayChar); private void DisplayCharacter(char displayChar) { output.Text = threadName + ":" + displayChar; } public void GenerateRandomCharacters() { threadName = Thread.CurrentThread.Name; while (true) { Thread.Sleep(generator.Next(1001)); lock (this) { while (suspended) { Monitor.Wait(this); } } char displayChar = (char)(generator.Next(26) + 65); output.Invoke(new DisplayDelegate(DisplayCharacter), new object[] { displayChar }); } } public void Toggle() { suspended = !suspended; output.BackColor = suspended ? Color.Red : Color.LightGreen; lock (this) { if (!suspended) { Monitor.Pulse(this); } } } } }
4,运行结果:可以看到3个线程分别更新Label的随机字母,点ComboBox随时暂停。
[END]