Worker Threads in C#

http://www.codeproject.com/KB/cs/workerthread.aspx

MainForm.cs

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;


namespace WorkerThread
{
 #region Public Delegates

 // delegates used to call MainForm functions from worker thread
 public delegate void DelegateAddString(String s);
 public delegate void DelegateThreadFinished();

 #endregion

 /// <summary>
 /// Main form for WorkerThread Sample
 /// </summary>
 public class MainForm : System.Windows.Forms.Form
 {
  #region Designer Code

  private System.Windows.Forms.Button btnStartThread;
  private System.Windows.Forms.Button btnStopThread;
  private System.Windows.Forms.Button btnExit;
  private System.Windows.Forms.ListBox listBox1;
  /// <summary>
  /// Required designer variable.
  /// </summary>
  private System.ComponentModel.Container components = null;

  #endregion

  #region Members

  // worker thread
  Thread m_WorkerThread;

  // events used to stop worker thread
  ManualResetEvent m_EventStopThread;
  ManualResetEvent m_EventThreadStopped;

  // Delegate instances used to cal user interface functions
  // from worker thread:
  public DelegateAddString m_DelegateAddString;
  public DelegateThreadFinished m_DelegateThreadFinished;


  #endregion

  #region Constructor, Destructor

  public MainForm()
  {
   //
   // Required for Windows Form Designer support
   //
   InitializeComponent();

   // initialize delegates
   m_DelegateAddString = new DelegateAddString(this.AddString);
   m_DelegateThreadFinished = new DelegateThreadFinished(this.ThreadFinished);

   // initialize events
   m_EventStopThread = new ManualResetEvent(false);
   m_EventThreadStopped = new ManualResetEvent(false);

  }

  /// <summary>
  /// Clean up any resources being used.
  /// </summary>
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if (components != null)
    {
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }

  #endregion


  #region Windows Form Designer generated code
  /// <summary>
  /// Required method for Designer support - do not modify
  /// the contents of this method with the code editor.
  /// </summary>
  private void InitializeComponent()
  {
   this.btnStartThread = new System.Windows.Forms.Button();
   this.btnStopThread = new System.Windows.Forms.Button();
   this.btnExit = new System.Windows.Forms.Button();
   this.listBox1 = new System.Windows.Forms.ListBox();
   this.SuspendLayout();
   //
   // btnStartThread
   //
   this.btnStartThread.Location = new System.Drawing.Point(416, 64);
   this.btnStartThread.Name = "btnStartThread";
   this.btnStartThread.Size = new System.Drawing.Size(104, 32);
   this.btnStartThread.TabIndex = 0;
   this.btnStartThread.Text = "Start Thread";
   this.btnStartThread.Click += new System.EventHandler(this.btnStartThread_Click);
   //
   // btnStopThread
   //
   this.btnStopThread.Enabled = false;
   this.btnStopThread.Location = new System.Drawing.Point(416, 136);
   this.btnStopThread.Name = "btnStopThread";
   this.btnStopThread.Size = new System.Drawing.Size(104, 32);
   this.btnStopThread.TabIndex = 1;
   this.btnStopThread.Text = "Stop Thread";
   this.btnStopThread.Click += new System.EventHandler(this.btnStopThread_Click);
   //
   // btnExit
   //
   this.btnExit.Location = new System.Drawing.Point(416, 224);
   this.btnExit.Name = "btnExit";
   this.btnExit.Size = new System.Drawing.Size(104, 32);
   this.btnExit.TabIndex = 2;
   this.btnExit.Text = "Exit";
   this.btnExit.Click += new System.EventHandler(this.btnExit_Click);
   //
   // listBox1
   //
   this.listBox1.ItemHeight = 16;
   this.listBox1.Location = new System.Drawing.Point(8, 8);
   this.listBox1.Name = "listBox1";
   this.listBox1.Size = new System.Drawing.Size(352, 276);
   this.listBox1.TabIndex = 3;
   //
   // MainForm
   //
   this.AutoScaleBaseSize = new System.Drawing.Size(6, 15);
   this.ClientSize = new System.Drawing.Size(552, 296);
   this.Controls.AddRange(new System.Windows.Forms.Control[] {
                    this.listBox1,
                    this.btnExit,
                    this.btnStopThread,
                    this.btnStartThread});
   this.Name = "MainForm";
   this.Text = "Worker thread sample";
   this.Closed += new System.EventHandler(this.MainForm_Closed);
   this.ResumeLayout(false);

  }
  #endregion

  #region Function Main

  /// <summary>
  /// The main entry point for the application.
  /// </summary>
  [STAThread]
  static void Main()
  {
   Application.Run(new MainForm());
  }

  #endregion

  #region Message Handlers

  // Start thread button is pressed
  private void btnStartThread_Click(object sender, System.EventArgs e)
  {
   listBox1.Items.Clear();
   btnStartThread.Enabled = false;
   btnStopThread.Enabled = true;

   // reset events
   m_EventStopThread.Reset();
   m_EventThreadStopped.Reset();

   // create worker thread instance
   m_WorkerThread = new Thread(new ThreadStart(this.WorkerThreadFunction));

   m_WorkerThread.Name = "Worker Thread Sample"; // looks nice in Output window

   m_WorkerThread.Start();

  }

  // Stop Thread button is pressed
  private void btnStopThread_Click(object sender, System.EventArgs e)
  {
   StopThread();
  }

  // Exit button is pressed.
  private void btnExit_Click(object sender, System.EventArgs e)
  {
   this.Close();
  }

  // Form is closed.
  // Stop thread if it is active.
  private void MainForm_Closed(object sender, System.EventArgs e)
  {
   StopThread();
  }

  #endregion


  #region Other Functions

  // Worker thread function.
  // Called indirectly from btnStartThread_Click
  private void WorkerThreadFunction()
  {
   LongProcess longProcess;

   longProcess = new LongProcess(m_EventStopThread, m_EventThreadStopped, this);

   longProcess.Run();
  }

  // Stop worker thread if it is running.
  // Called when user presses Stop button of form is closed.
  private void StopThread()
  {
   if ( m_WorkerThread != null  &&  m_WorkerThread.IsAlive )  // thread is active
   {
    // set event "Stop"
    m_EventStopThread.Set();

    // wait when thread  will stop or finish
    while (m_WorkerThread.IsAlive)
    {
     // We cannot use here infinite wait because our thread
     // makes syncronous calls to main form, this will cause deadlock.
     // Instead of this we wait for event some appropriate time
     // (and by the way give time to worker thread) and
     // process events. These events may contain Invoke calls.
     if ( WaitHandle.WaitAll(
      (new ManualResetEvent[] {m_EventThreadStopped}),
      100,
      true) )
     {
      break;
     }

     Application.DoEvents();
    }
   }

   ThreadFinished();  // set initial state of buttons
  }

  // Add string to list box.
  // Called from worker thread using delegate and Control.Invoke
  private void AddString(String s)
  {
   listBox1.Items.Add(s);

   
  }

  // Set initial state of controls.
  // Called from worker thread using delegate and Control.Invoke
  private void ThreadFinished()
  {
   btnStartThread.Enabled = true;
   btnStopThread.Enabled = false;
  }

  #endregion


 }
}
================================

LongProcess.cs

using System;
using System.Windows.Forms;
using System.Threading;


namespace WorkerThread
{
 /// <summary>
 /// Class emulates long process which runs in worker thread
 /// and makes synchronous user UI operations.
 /// </summary>
 public class LongProcess
 {
  #region Members

  // Main thread sets this event to stop worker thread:
  ManualResetEvent m_EventStop;

  // Worker thread sets this event when it is stopped:
  ManualResetEvent m_EventStopped;

  // Reference to main form used to make syncronous user interface calls:
  MainForm m_form;

  #endregion

  #region Functions

  public LongProcess(ManualResetEvent eventStop,
                  ManualResetEvent eventStopped,
                  MainForm form)
  {
   m_EventStop = eventStop;
   m_EventStopped = eventStopped;
   m_form = form;
  }

  // Function runs in worker thread and emulates long process.
  public void Run()
  {
   int i;
   String s;

   for (i = 1; i <= 10; i++)
   {
    // make step
    s = "Step number " + i.ToString() + " executed";

    Thread.Sleep(400);

    // Make synchronous call to main form.
    // MainForm.AddString function runs in main thread.
    // To make asynchronous call use BeginInvoke
    m_form.Invoke(m_form.m_DelegateAddString, new Object[] {s});


    // check if thread is cancelled
    if ( m_EventStop.WaitOne(0, true) )
    {
     // clean-up operations may be placed here
     // ...

     // inform main thread that this thread stopped
     m_EventStopped.Set();

     return;
    }
   }

   // Make asynchronous call to main form
   // to inform it that thread finished
   m_form.Invoke(m_form.m_DelegateThreadFinished, null);
  }

  #endregion
 }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值