//关于线程在C#中的描述,请参阅本BLOG的<<C#线程简述>>
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;//使用线程的命名空间
//应用程序的功能:输出1-255之间的所有素数
namespace WindowsThreadTest
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;//开始线程:Start
private System.Windows.Forms.Button button2;//暂停线程:Pause
private System.Windows.Forms.Button button3;//恢复线程:Resume
private System.Windows.Forms.Button button4;//终止线程:Stop
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
private System.Windows.Forms.Button button5;//退出应用程序
private System.Windows.Forms.ListBox listBox1;//列表框,输出结果
public Thread primeNumberThread;//声明线程类 Thread 的对象
public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
//初始化功能按钮
button1.Enabled=true;
button2.Enabled=false;
button3.Enabled=false;
button4.Enabled=false;
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
//因为用户界面与GeneratePrimeNumbers()方法在不同的线程中运行,
//故使用委托,通知UI线程更新列表控件。
//这样做,不会超出线程的边界,应用程序的稳定性也不会降低。
public delegate void UpdateData(string returnVal);
private void GeneratePrimeNumbers()//生成素数,并且输出结果,显示在列表框内
{
//实例的主要目的是使用多线程机制,而不去深入探讨算法。
int lngCounter=2;
int lngNumber=3;
int lngDivideByCounter;
bool blnIsPrime;
int[] PrimeArray=new int[256];
string[] args=new string[]{"2"};
UpdateData UIDel=new UpdateData(UpdateUI);
PrimeArray[1]=2;
//listBox1.Items.Add(2);
this.Invoke(UIDel,args);//通知UI更新自身。
//while(lngCounter<=255)
while(lngNumber<=255)
{
blnIsPrime=true;
for(lngDivideByCounter=1;PrimeArray[lngDivideByCounter]*PrimeArray[lngDivideByCounter]<=lngNumber;lngDivideByCounter++)
{
if(lngNumber%PrimeArray[lngDivideByCounter]==0)
{
blnIsPrime=false;
break;
}
}
if(blnIsPrime)
{
PrimeArray[lngCounter]=lngNumber;
lngCounter++;
args[0]=lngNumber.ToString();
this.Invoke(UIDel,args);//
//listBox1.Items.Add(lngNumber);
//若不使用委托,可以使用 Add()方法输出结果。
}
Thread.Sleep(500);//主线程睡眠500毫秒。
lngNumber+=2;
// button1.Enabled=false;
// button2.Enabled=true;
// button3.Enabled=false;
// button4.Enabled=false;
}
//还原最初状态
button1.Enabled=true;
button2.Enabled=false;
button3.Enabled=false;
button4.Enabled=false;
}
void UpdateUI(string result)
{
listBox1.Items.Add(result);
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.button4 = new System.Windows.Forms.Button();
this.button5 = new System.Windows.Forms.Button();
this.listBox1 = new System.Windows.Forms.ListBox();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(96, 40);
this.button1.Name = "button1";
this.button1.TabIndex = 1;
this.button1.Text = "Start";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(96, 80);
this.button2.Name = "button2";
this.button2.TabIndex = 2;
this.button2.Text = "Pause";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button3
//
this.button3.Location = new System.Drawing.Point(96, 120);
this.button3.Name = "button3";
this.button3.TabIndex = 3;
this.button3.Text = "Resume";
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// button4
//
this.button4.Location = new System.Drawing.Point(96, 160);
this.button4.Name = "button4";
this.button4.TabIndex = 4;
this.button4.Text = "Stop";
this.button4.Click += new System.EventHandler(this.button4_Click);
//
// button5
//
this.button5.Location = new System.Drawing.Point(96, 200);
this.button5.Name = "button5";
this.button5.TabIndex = 6;
this.button5.Text = "Exit";
this.button5.Click += new System.EventHandler(this.button5_Click);
//
// listBox1
//
this.listBox1.ItemHeight = 12;
this.listBox1.Location = new System.Drawing.Point(8, 8);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(80, 292);
this.listBox1.TabIndex = 7;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(192, 310);
this.Controls.Add(this.listBox1);
this.Controls.Add(this.button5);
this.Controls.Add(this.button4);
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Prime Numbers";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]//单线程模式下运行程序
static void Main()
{
Application.Run(new Form1());//应用程序运行当前类的构造函数
}
private void button1_Click(object sender, System.EventArgs e)
{
listBox1.Items.Clear();
//创建 ThreadStart的委托实例
primeNumberThread=new Thread(new ThreadStart(GeneratePrimeNumbers));
//定义线程的名称
primeNumberThread.Name="Prime Numbers Example";
//设置线程的优先级别
primeNumberThread.Priority=ThreadPriority.Lowest;
//设置此时的按钮状态
button1.Enabled=false;
button2.Enabled=true;
button3.Enabled=false;
button4.Enabled=false;
//判断当前线程的状态。
if(primeNumberThread.ThreadState==System.Threading.ThreadState.WaitSleepJoin)
MessageBox.Show("1");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.AbortRequested)
MessageBox.Show("2");
else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Background)
MessageBox.Show("3");
else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Running)
MessageBox.Show("4");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.Stopped)
MessageBox.Show("5");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.StopRequested)
MessageBox.Show("6");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.Suspended)
MessageBox.Show("7");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.SuspendRequested)
MessageBox.Show("8");
else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Unstarted)
MessageBox.Show("9");//在运行之前,判断出当前线程处于Unstarted状态
else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Aborted)
MessageBox.Show("0");
else MessageBox.Show("否");
primeNumberThread.Start();//开始执行线程
//判断当前线程的状态。
if(primeNumberThread.ThreadState==System.Threading.ThreadState.WaitSleepJoin)
MessageBox.Show("1");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.AbortRequested)
MessageBox.Show("2");
else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Background)
MessageBox.Show("3");
else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Running)
MessageBox.Show("4");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.Stopped)
MessageBox.Show("5");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.StopRequested)
MessageBox.Show("6");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.Suspended)
MessageBox.Show("7");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.SuspendRequested)
MessageBox.Show("8");
else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Unstarted)
MessageBox.Show("9");//仍然处于此状态???
else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Aborted)
MessageBox.Show("0");
else MessageBox.Show("否");
}
private void button3_Click(object sender, System.EventArgs e)
{
try
{
//判断当前线程的状态。
if(primeNumberThread.ThreadState==System.Threading.ThreadState.WaitSleepJoin)
MessageBox.Show("1");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.AbortRequested)
MessageBox.Show("2");
else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Background)
MessageBox.Show("3");
else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Running)
MessageBox.Show("4");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.Stopped)
MessageBox.Show("5");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.StopRequested)
MessageBox.Show("6");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.Suspended)
MessageBox.Show("7");
else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.SuspendRequested)
MessageBox.Show("8");
else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Unstarted)
MessageBox.Show("9");
else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Aborted)
MessageBox.Show("WSJ");
else //以上状态都不符合
{
MessageBox.Show("Resume Now !");
primeNumberThread.Resume();//继续进行,恢复被挂起的进程
button3.Enabled=false;
button1.Enabled=true;
button2.Enabled=true;
button4.Enabled=true;
}
}
catch(Exception EX)
{
MessageBox.Show(EX.ToString());
}
}
private void button4_Click(object sender, System.EventArgs e)
{
try
{
button1.Enabled=true;
button2.Enabled=false;
button3.Enabled=false;
button4.Enabled=false;
primeNumberThread.Abort();//终止线程
}
catch(Exception EX)
{
MessageBox.Show(EX.ToString());
}
}
private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{
}
private void button2_Click(object sender, System.EventArgs e)
{
/*******/
// if(primeNumberThread.ThreadState == System.Threading.ThreadState.WaitSleepJoin)
try
{
if(primeNumberThread.ThreadState == System.Threading.ThreadState.WaitSleepJoin)
{
MessageBox.Show("Suspend Now !");
primeNumberThread.Suspend();//将当前的线程挂起
button1.Enabled=false;
button2.Enabled=false;//
button3.Enabled=true;
button4.Enabled=false;
// }
// else
// {
// MessageBox.Show("CVB");
}
//*********************************//
// 以下注释的这段代码,列举所用线程状态的属性:用来测试判断当前的线程处于哪个状态。
// if(primeNumberThread.ThreadState==System.Threading.ThreadState.WaitSleepJoin)
// MessageBox.Show("1");
// else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.AbortRequested)
// MessageBox.Show("2");
// else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Background)
// MessageBox.Show("3");
// else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Running)
// MessageBox.Show("4");
// else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.Stopped)
// MessageBox.Show("5");
// else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.StopRequested)
// MessageBox.Show("6");
// else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.Suspended)
// MessageBox.Show("7");
// else if(primeNumberThread.ThreadState ==System.Threading.ThreadState.SuspendRequested)
// MessageBox.Show("8");
// else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Unstarted)
// MessageBox.Show("9");
// else if (primeNumberThread.ThreadState ==System.Threading.ThreadState.Aborted)
// MessageBox.Show("0");
// else MessageBox.Show("Sorry !");
//**********************************//
}
catch(Exception EX)
{
MessageBox.Show(EX.ToString());
}
}
private void button5_Click(object sender, System.EventArgs e)
{
Application.Exit();//应用程序退出
}
}
}
/***************************
* 读者是否注意到上述代码的问题。
* 每当需要获取线程当前的状态时,实际情况总是会和理论的不相符合。
* 比如,想让当前挂起的线程恢复:
* 我们先取当前的状态,理论下,当前的状态为Suspended,可是寻遍命名空间中线程的10种状态值,
* 竟然发现均不符合。
* 那么疑问,当前是什么状态呢?我们怎样将其恢复呢?
* 尝试使用Resume()方法,竟然奏效了!
* 类似的情况,在“暂停线程”时也遇到了。
* 那么又要疑问:
* 如此的编写程序,是不是线程的状态无法驾驭了?
* 我们又怎么去知道线程当前是什么状态,非要一个一个取值尝试吗?
***************************/
参考文献
Tobin Titus , Fabio Claudio Ferracchiati 著,王敏 译 . C#线程参考手册 . 北京:清华大学出版社, 2003