C# Source Code: Example showing how to Suspend and Resume Threads
[
Home
|
Contents
|
Search
|
Reply
| Previous | Next ]
C# Source Code
Example showing how to Suspend and Resume Threads
By:
Andrew Baker
Email (spam proof):
Email the originator of this post
Date:
Sunday, October 10, 2004
Hits:
3695
Category:
Threading/Asynchronous operations
Article:
The Suspend() and Resume() methods of the Thread class can be used to suspend and resume a thread. The Suspend() method will suspend the current thread indefinitely until another thread wakes it up. When the Suspend() is called the thread is placed in the SuspendRequested or Suspended state until a Resume() is called. Unlike the Interrupt() method, the Resume() method will not generate an exception in suspended Thread. Below is a simple windows form example that creates a counter in a seperate thread that updates a label. The example shows how to stop and start the counter thread. using System; using System.Drawing; using System.Collections; using System.Diagnostics; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Threading; namespace VBusers.Threading { ///
/// Demonstrates how to suspend and resume threads. ///
public class frmSuspendAndResume : System.Windows.Forms.Form { #region Private Variables private Thread _threadCounter; private int _count = 0; #endregion private System.Windows.Forms.Button btnStart; private System.Windows.Forms.Button btnResume; private System.Windows.Forms.Button btnPause; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label lblCount; ///
/// Required designer variable. ///
private System.ComponentModel.Container components = null; public frmSuspendAndResume() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // } ///
/// Clean up any resources being used. ///
protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code ///
/// Required method for Designer support - do not modify /// the contents of this method with the code editor. ///
private void InitializeComponent() { this.btnStart = new System.Windows.Forms.Button(); this.btnResume = new System.Windows.Forms.Button(); this.btnPause = new System.Windows.Forms.Button(); this.lblCount = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.SuspendLayout(); // // btnStart // this.btnStart.Location = new System.Drawing.Point(6, 76); this.btnStart.Name = "btnStart"; this.btnStart.Size = new System.Drawing.Size(90, 26); this.btnStart.TabIndex = 0; this.btnStart.Text = "&Start"; this.btnStart.Click += new System.EventHandler(this.btnStart_Click); // // btnResume // this.btnResume.Location = new System.Drawing.Point(201, 76); this.btnResume.Name = "btnResume"; this.btnResume.Size = new System.Drawing.Size(90, 26); this.btnResume.TabIndex = 1; this.btnResume.Text = "&Resume"; this.btnResume.Click += new System.EventHandler(this.btnResume_Click); // // btnPause // this.btnPause.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnPause.Location = new System.Drawing.Point(103, 76); this.btnPause.Name = "btnPause"; this.btnPause.Size = new System.Drawing.Size(90, 26); this.btnPause.TabIndex = 1; this.btnPause.Text = "&Pause"; this.btnPause.Click += new System.EventHandler(this.btnPause_Click); // // lblCount // this.lblCount.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.lblCount.Location = new System.Drawing.Point(92, 22); this.lblCount.Name = "lblCount"; this.lblCount.Size = new System.Drawing.Size(188, 20); this.lblCount.TabIndex = 2; this.lblCount.Text = "0"; this.lblCount.TextAlign = System.Drawing.ContentAlignment.MiddleRight; // // label2 // this.label2.Location = new System.Drawing.Point(18, 22); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(58, 20); this.label2.TabIndex = 3; this.label2.Text = "Count:"; // // frmSuspendAndResume // this.AcceptButton = this.btnStart; this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.CancelButton = this.btnPause; this.ClientSize = new System.Drawing.Size(300, 110); this.Controls.Add(this.label2); this.Controls.Add(this.lblCount); this.Controls.Add(this.btnPause); this.Controls.Add(this.btnResume); this.Controls.Add(this.btnStart); this.Name = "frmSuspendAndResume"; this.Text = "Suspend"; this.Closing += new System.ComponentModel.CancelEventHandler(this.frmSuspend_Closing); this.ResumeLayout(false); } #endregion ///
/// The main entry point for the application. ///
[STAThread] static void Main() { Application.Run(new frmSuspendAndResume()); } #region Form Event Handlers ///
/// Called by the start button ///
///
///
private void btnStart_Click(object sender, System.EventArgs e) { _threadCounter = new Thread(new ThreadStart(_StartCounting)); _threadCounter.Start(); btnStart.Enabled = false; btnResume.Enabled = false; btnPause.Enabled = true; } ///
/// Called by the Pause button. /// Suspends the counting. ///
///
///
private void btnPause_Click(object sender, System.EventArgs e) { btnResume.Enabled = true; btnPause.Enabled = false; _threadCounter.Suspend(); } ///
/// Called by the resume button. /// Resumes the counting. ///
///
///
private void btnResume_Click(object sender, System.EventArgs e) { btnResume.Enabled = false; btnPause.Enabled = true; _threadCounter.Resume(); } ///
/// Form Close. Make sure you bring down any threads before quiting the application /// otherwise the process will not exit. ///
///
///
private void frmSuspend_Closing(object sender, System.ComponentModel.CancelEventArgs e) { try { if ( _threadCounter != null) { // Read the thread state Debug.WriteLine("Thread State " + _threadCounter.ThreadState.ToString()); int state = (int)_threadCounter.ThreadState; // Check if the thread is suspended if ((state & (int)System.Threading.ThreadState.Suspended) > 0) { // HACK: CANNOT ABORT A SUSPENDED THREAD // Restarting the thread before aborting Debug.Write("Resuming Thread..."); _threadCounter.Resume(); } if ( (state & (int)System.Threading.ThreadState.Stopped) == 0 ) { // Abort the thread Debug.Write("Aborting Thread (will throw exception)..."); _threadCounter.Abort(); } } } catch(Exception ex) { Debug.Write("Caught Exception While Termination Thread. " + ex.Message); } } #endregion #region Private Methods ///
/// Increments a number and updates the UI with this number /// Called by main worked thread. ///
private void _StartCounting() { try { do { // Perform work Thread.Sleep(500); _count = _count + 1; // Update the label control if( lblCount.InvokeRequired ) { // Running in a non UI thread. // Synchronise onto UI thread using a synchronised delegate. lblCount.Invoke(new MethodInvoker(_UpdateLabelCount)); } else { // Being call from UI thread, so no need to synchronise _UpdateLabelCount(); } } while(true); } catch(Exception ex) { Debug.WriteLine("Error in StartCounting... " + ex.Message); } } ///
/// Updates the text in the lable ///
private void _UpdateLabelCount() { lblCount.Text = _count.ToString(); } #endregion } }
Terms and Conditions
Support this site
Download a trial version of the best FTP application on the internet