线程同步是我们常常遇到的问题,下面这个实验就是线程同步的例子。其功能是先让进程1执行,然后再线程1执行一会后再让线程2执行,当线程2执行完毕后,再按线程1接着执行。
在这个实验中,要用到在一个线程中操用另一个线程的控件的知识。
好了,不多说了,下面开始实验吧。
实验结果分析:
首先同时启线程1 与线程2,当线程1输出A后,我们让线程1 处于阻塞状态。让线程2开始执行。由于线程1会等待线程2执行完毕,只有线程2执行完毕后线程1才有运行的机会。但同于线程2是一个死循环,因此,我们只有手动关闭线程2后线程1才得以执行。
为了文便说明各控件的属性与功能,特将from.Desing.cs代码贴出来,如下:
namespace ProcessTest
{
partial class ThreadCoordinate
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.btnCoordinate = new System.Windows.Forms.Button();
this.btnQuit = new System.Windows.Forms.Button();
this.txtDisplay = new System.Windows.Forms.RichTextBox();
this.btnEndThread1 = new System.Windows.Forms.Button();
this.btnEndThread2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnCoordinate
//
this.btnCoordinate.Location = new System.Drawing.Point(12, 275);
this.btnCoordinate.Name = "btnCoordinate";
this.btnCoordinate.Size = new System.Drawing.Size(86, 23);
this.btnCoordinate.TabIndex = 1;
this.btnCoordinate.Text = "Coordinate";
this.btnCoordinate.UseVisualStyleBackColor = true;
this.btnCoordinate.Click += new System.EventHandler(this.btnCoordinate_Click);
//
// btnQuit
//
this.btnQuit.Location = new System.Drawing.Point(309, 275);
this.btnQuit.Name = "btnQuit";
this.btnQuit.Size = new System.Drawing.Size(94, 23);
this.btnQuit.TabIndex = 2;
this.btnQuit.Text = "End Thread";
this.btnQuit.UseVisualStyleBackColor = true;
this.btnQuit.Click += new System.EventHandler(this.btnQuit_Click);
//
// txtDisplay
//
this.txtDisplay.Location = new System.Drawing.Point(12, 12);
this.txtDisplay.Name = "txtDisplay";
this.txtDisplay.Size = new System.Drawing.Size(350, 256);
this.txtDisplay.TabIndex = 3;
this.txtDisplay.Text = "";
//
// btnEndThread1
//
this.btnEndThread1.Location = new System.Drawing.Point(104, 274);
this.btnEndThread1.Name = "btnEndThread1";
this.btnEndThread1.Size = new System.Drawing.Size(104, 23);
this.btnEndThread1.TabIndex = 2;
this.btnEndThread1.Text = "End Thread1";
this.btnEndThread1.UseVisualStyleBackColor = true;
this.btnEndThread1.Click += new System.EventHandler(this.btnEndThread1_Click);
//
// btnEndThread2
//
this.btnEndThread2.Location = new System.Drawing.Point(214, 275);
this.btnEndThread2.Name = "btnEndThread2";
this.btnEndThread2.Size = new System.Drawing.Size(89, 23);
this.btnEndThread2.TabIndex = 4;
this.btnEndThread2.Text = "End Thread2";
this.btnEndThread2.UseVisualStyleBackColor = true;
this.btnEndThread2.Click += new System.EventHandler(this.btnEndThread2_Click);
//
// ThreadCoordinate
//
this.AutoScaleDimensions = new System.Drawing.SizeF( 6F , 12F );
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(424, 325);
this.Controls.Add(this.btnEndThread2);
this.Controls.Add(this.txtDisplay);
this.Controls.Add(this.btnEndThread1);
this.Controls.Add(this.btnQuit);
this.Controls.Add(this.btnCoordinate);
this.Name = "ThreadCoordinate";
this.Text = "ThreadCoordinate";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button btnCoordinate;
private System.Windows.Forms.Button btnQuit;
private System.Windows.Forms.RichTextBox txtDisplay;
private System.Windows.Forms.Button btnEndThread1;
private System.Windows.Forms.Button btnEndThread2;
}
}
对应界面如下:
程序代码如下:
public partial class ThreadCoordinate : Form
{
private Thread _thread1;
private Thread _thread2;
//in order to operator a activeX with many thread,define a delegate;
delegate void WriteContent(string str);
WriteContent temp;
/// <summary>
/// initial the class
/// </summary>
public ThreadCoordinate()
{
InitializeComponent();
temp = new WriteContent(Write);
}
/// <summary>
/// start the two thread.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnCoordinate_Click(object sender, EventArgs e)
{
_thread1 = new Thread(new ThreadStart(Method1));
_thread2 = new Thread(new ThreadStart (Method2 ));
_thread1.Start();
_thread2.Start();
}
/// <summary>
/// _thread1's code
/// </summary>
private void Method1()
{
txtDisplay.Invoke(temp,"a");
_thread2.Join();
while (true)
{
Thread.Sleep(100);
txtDisplay.Invoke(temp, "C");
}
}
/// <summary>
/// _thread2's code
/// </summary>
private void Method2()
{
while (true)
{
Thread.Sleep(100);
txtDisplay.Invoke(temp, "b");
}
}
/// <summary>
/// write content to txtDisplay
/// </summary>
/// <param name="str">string that display in the txtDisplay</param>
private void Write(string str)
{
txtDisplay.Text += str;
}
/// <summary>
/// End all the thread ,include thread1 and thread2
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnQuit_Click(object sender, EventArgs e)
{
try
{
_thread1.Abort();
_thread1.Join();
_thread2.Abort();
_thread2.Join();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// end thread2;
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnEndThread2_Click(object sender, EventArgs e)
{
try
{
_thread2.Abort();
_thread2.Join();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message );
}
}
/// <summary>
/// end thread1
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnEndThread1_Click(object sender, EventArgs e)
{
try
{
_thread1.Abort();
_thread1.Join();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
实验结果