My Threading Start

/*
* C# Programmers Pocket Consultant
* Author: Gregory S. MacBeth
* Email: gmacbeth@comporium.net
* Create Date: June 27, 2003
* Last Modified Date:
* Version: 1
*/
using System;
using System.Threading;

namespace Client.Chapter_15___Threading
{
public class MyThreadingClassChapter_15___Threading
{
static void Main(string[] args)
{
My2ndClass me = new My2ndClass();
Thread[] MyThreads = new Thread[10];

for (int I = 0; I < 100; I++) { MyThreads[I] = new Thread(new ThreadStart(me.MyThreadProc)); MyThreads[I].Start(); } } } class My2ndClass { private int counter; public void MyThreadProc() { IncCounter(); } private void IncCounter() { lock (this) { counter++; } } } } [/csharp]

Creating Threads

/*
* C# Programmers Pocket Consultant
* Author: Gregory S. MacBeth
* Email: gmacbeth@comporium.net
* Create Date: June 27, 2003
* Last Modified Date:
* Version: 1
*/
using System;
using System.Threading;

namespace Client.Chapter_15___Threading
{
public class CreatingThreads
{
static void Main(string[] args)
{
Thread MyNewThread = new Thread(new ThreadStart(ThreadProc));

MyNewThread.Start();
MyNewThread.Join();
}
protected static void ThreadProc()
{
for (int i = 0; i < 100; i++) { Console.WriteLine(i); } } } } [/csharp]

Thread and GUI

/*
Professional Windows GUI Programming Using C#
by Jay Glynn, Csaba Torok, Richard Conway, Wahid Choudhury,
Zach Greenvoss, Shripad Kulkarni, Neil Whitlow

Publisher: Peer Information
ISBN: 1861007663
*/
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;

namespace Wrox.WindowsGUIProgramming.Chapter9
{
///

/// Summary description for Form1.
///

///
struct _threadstart
{
public ThreadStart threadstart;
public DateTime dt;
}

public class frmWasteTime : System.Windows.Forms.Form
{
private System.Windows.Forms.Button butWasteTime;
private System.Windows.Forms.TextBox textBox1;
///

/// Required designer variable.
///

private System.ComponentModel.Container components = null;
private System.Windows.Forms.ListBox lbThreads;
private System.Windows.Forms.TextBox txtNoOfThreads;
private System.Windows.Forms.Button btThreadStart;

private System.IAsyncResult m_EndInvoke = null;

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

//
// TODO: Add any constructor code after InitializeComponent call
//
this.Show();
//TakeTime();
}

///

/// 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.butWasteTime = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.lbThreads = new System.Windows.Forms.ListBox();
this.txtNoOfThreads = new System.Windows.Forms.TextBox();
this.btThreadStart = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// butWasteTime
//
this.butWasteTime.Location = new System.Drawing.Point(88, 32);
this.butWasteTime.Name = “butWasteTime”;
this.butWasteTime.TabIndex = 0;
this.butWasteTime.Text = “Waste Time”;
this.butWasteTime.Click += new System.EventHandler(this.butWasteTime_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(184, 24);
this.textBox1.Name = “textBox1”;
this.textBox1.TabIndex = 1;
this.textBox1.Text = “”;
//
// lbThreads
//
this.lbThreads.Location = new System.Drawing.Point(8, 64);
this.lbThreads.Name = “lbThreads”;
this.lbThreads.Size = new System.Drawing.Size(280, 277);
this.lbThreads.TabIndex = 2;
//
// txtNoOfThreads
//
this.txtNoOfThreads.Location = new System.Drawing.Point(8, 352);
this.txtNoOfThreads.Name = “txtNoOfThreads”;
this.txtNoOfThreads.TabIndex = 3;
this.txtNoOfThreads.Text = “”;
//
// btThreadStart
//
this.btThreadStart.Location = new System.Drawing.Point(128, 352);
this.btThreadStart.Name = “btThreadStart”;
this.btThreadStart.Size = new System.Drawing.Size(160, 23);
this.btThreadStart.TabIndex = 4;
this.btThreadStart.Text = “Start”;
this.btThreadStart.Click += new System.EventHandler(this.btThreadStart_Click);
//
// frmWasteTime
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(296, 390);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.btThreadStart,
this.txtNoOfThreads,
this.lbThreads,
this.textBox1,
this.butWasteTime});
this.Name = “frmWasteTime”;
this.Text = “Lock Form”;
this.Paint += new System.Windows.Forms.PaintEventHandler(this.painting);
this.ResumeLayout(false);

}
#endregion

///

/// The main entry point for the application.
///

[STAThread]
static void Main()
{
Application.Run(new frmWasteTime());
}

private void TakeTime()
{
int j = 0;
for(int i=0;i<320-j;i++) { System.Diagnostics.Debug.Write(i); } j++; } private void butWasteTime_Click(object sender, System.EventArgs e) { IAsyncResult m_EndInvoke2 = null; ThreadStart threadstart = new ThreadStart(TakeTime); m_EndInvoke = threadstart.BeginInvoke(new AsyncCallback(MethodBeginInvoke), String.Copy("test")); ThreadStart threadstart2 = new ThreadStart(TakeTime); m_EndInvoke2 = threadstart.BeginInvoke(new AsyncCallback(MethodBeginInvoke), null); //m_EndInvoke.AsyncWaitHandle.WaitOne(); threadstart.EndInvoke(m_EndInvoke); threadstart.EndInvoke(m_EndInvoke2); /*while(true) { if(m_EndInvoke.IsCompleted) MessageBox.Show("finally!!!"); break; }*/ } private void MethodBeginInvoke(System.IAsyncResult ar) { if(ar.CompletedSynchronously) MessageBox.Show("TakeTime() called synchronously"); else MessageBox.Show("TakeTime() called asynchronously"); } protected override void OnPaint(PaintEventArgs pe) { System.Diagnostics.Debug.Write("Paint event called"); } private void painting(object sender, System.Windows.Forms.PaintEventArgs e) { System.Diagnostics.Debug.Write("Paint event called"); } //System.Threading.ThreadStart[] threads; //DateTime[] dateTimeThread; _threadstart[] th; DateTime dtStart; DateTime dtEnd; private void btThreadStart_Click(object sender, System.EventArgs e) { th = new _threadstart[Convert.ToInt32(txtNoOfThreads.Text)]; //threads = (ThreadStart[])Array.CreateInstance(typeof(ThreadStart), Convert.ToInt16(txtNoOfThreads.Text)); //dateTimeThread = (DateTime[])Array.CreateInstance(typeof(DateTime), threads.Length); dtStart = DateTime.Now; for(int i = 0; i < th.Length; i++) { th[i].threadstart = new ThreadStart(TakeTime); th[i].threadstart.BeginInvoke(new AsyncCallback(ThreadFinished), i); th[i].dt = DateTime.Now; } /*while(true) { for(int i = 0; i < threads.Length; i++) { if((threads[i].ThreadState == System.Threading.ThreadState.Suspended) && finished[i].Equals(false)) { //put something into the listbox lbThreads.Items.Insert(i, "Thread "+i+" finished - "+(DateTime.Now.Subtract(dateTimeThread[i]))); finished[i] = true; } Refresh(); } }*/ } void FinalCallback(string blank) { dtEnd = DateTime.Now.Subtract(new TimeSpan(dtStart.Ticks)); lbThreads.Items.Add("Total Thread Time: "+((dtEnd.Minute*60)+dtEnd.Second).ToString()+" seconds"); lbThreads.Items.Add("Average Thread Time: "+(((dtEnd.Minute*60)+dtEnd.Second)/th.Length)+" seconds"); } void UpdateListbox(string listboxText) { lbThreads.Items.Add(listboxText); } delegate void ItemAdd(string item); private void ThreadFinished(IAsyncResult ar) { ItemAdd ia = new ItemAdd(UpdateListbox); ItemAdd ib = new ItemAdd(FinalCallback); int i = (int)ar.AsyncState; string state = "Thread "+(i+1)+" finished - "+(DateTime.Now.Subtract(th[i].dt)).ToString(); //put something into the listbox if(lbThreads.InvokeRequired) { lbThreads.Invoke(ia, new Object[] {state}); } else { lbThreads.Items.Add(state); } if(i==(th.Length-1)) lbThreads.Invoke(ib, new Object[]{""}); } } } [/csharp]

Demonstrates hiding a form and then doing background processing in a second thread


   

/*
C# Programming Tips &amp; Techniques
by Charles Wright, Kris Jamsa

Publisher: Osborne/McGraw-Hill (December 28, 2001)
ISBN: 0072193794
*/

// HideForm.cs -- Demonstrates hiding a form and then doing background
//                processing in a second thread.
//
//                Compile this program with the following command line:
//                    C:>csc HideForm.cs
using System;
using System.Windows.Forms;
using System.Threading;

namespace HideForm
{
    public class HideForm : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button button1;
        public HideForm()
        {
            Text = "A Simple Form";
            button1 = new Button ();
            SuspendLayout();
            button1.Text = "Cancel";
            button1.Name = "button1";
            button1.Size = new System.Drawing.Size (72, 30);
            button1.Location = new System.Drawing.Point ((ClientRectangle.Width - button1.Size.Width) / 2, ClientRectangle.Height - 35);
            Controls.AddRange(new System.Windows.Forms.Control[] {this.button1});
            button1.Click += new System.EventHandler(OnClickButton1);
            this.Closed += new System.EventHandler(OnClickButton1);
            ResumeLayout (false);
            this.Visible = false;
        }
        [STAThread]
        static void Main() 
        {
            HideForm form = new HideForm();
            Thread delay = new Thread (new ThreadStart(form.DelayVisible));
            delay.Start ();
            Application.Run();
        }

        public void DelayVisible ()
        {
            while (true)
            {
                Thread.Sleep (2500);
                DialogResult result = MessageBox.Show ("Display Form?", "Display", MessageBoxButtons.YesNoCancel);
                switch (result)
                {
                    case DialogResult.Yes:
                        this.ShowDialog();
                        return;
                    case DialogResult.No:
                        continue;
                    case DialogResult.Cancel:
                        Application.Exit ();
                        break;
                }
                return;
            }
        }
        private void OnClickButton1(object sender, System.EventArgs e)
        {
            Application.Exit ();
        }
    }
}


           
          


Uses Wait and Pulse to enable producer and consumer threads to cooperate in using a buffer

   

/*
Revised from code in "Computing with C# and the .NET Framework"

# Paperback: 753 pages
# Publisher: Jones and Bartlett Publishers, Inc.; Bk&amp;CD-Rom edition (February 2003)
# Language: English
# ISBN: 0763723398
# Product Dimensions: 8.9 x 7.7 x 1.1 inches
*/


using System;
using System.Runtime.CompilerServices;
using System.Threading;  

  class Buffer {
    public const int size = 3;
    int[] buffer = new int [size];             
    int putpos=0;
    int getpos=0;
    int number=0;

    [MethodImpl(MethodImplOptions.Synchronized)]
    public void Put(int value) {
      if (number == size) {
        Console.WriteLine("Cannot put -- Buffer full");
        Monitor.Wait(this);
      }
      number++;
      buffer[putpos] = value;
      Console.WriteLine("Put "+value);
      putpos = (putpos + 1) % size;
      if (number == 1) Monitor.Pulse(this);         
    }

    [MethodImpl(MethodImplOptions.Synchronized)]
    public int Get() {
      if (number == 0) {
         Console.WriteLine("Buffer empty");
         Monitor.Wait(this);
      }
      number--;
      int n = buffer[getpos];
      Console.WriteLine("Get "+n);
      getpos = (getpos + 1) % size;
      if (number == size - 1) Monitor.Pulse(this);    
      return n;
    }
  }
  class Producer {
     Buffer buf;
     public Producer(Buffer b) { 
        buf = b;
        Thread thread = new Thread(new ThreadStart(Run));
        thread.Start();  
     }      
     public void Run() {
       for(; true; ) {
             buf.Put(0);
       }
     }
  }
  class Consumer {
     Buffer buf;
     public Consumer(Buffer b) { 
       buf = b;
       Thread thread = new Thread(new ThreadStart(Run));
       thread.Start();  
     }
     public void Run() {
       for (; true;) {
           buf.Get();
       }
     }
  }

public class PutGet {
  public static void Main(String[] args) {
    Buffer b = new Buffer();
    Producer p = new Producer(b);
    Consumer c = new Consumer(b);
  }
}
           
          


Producer and consumer with a Circular Buffer

/*
Code revised from Book published by
(C) Copyright 1992-2006 by Deitel & Associates, Inc. and
Pearson Education, Inc. All Rights Reserved.

*/
using System;
using System.Threading;

public class Producer
{
private CircularBuffer sharedLocation;
private Random randomSleepTime;

public Producer( CircularBuffer shared, Random random )
{
sharedLocation = shared;
randomSleepTime = random;
}
public void Produce()
{
for ( int count = 1; count <= 10; count++ ) { Thread.Sleep( randomSleepTime.Next( 1, 3001 ) ); sharedLocation.Buffer = count; } Console.WriteLine( "{0} done producing. Terminating {0}.", Thread.CurrentThread.Name ); } } public class Consumer { private CircularBuffer sharedLocation; private Random randomSleepTime; public Consumer( CircularBuffer shared, Random random ) { sharedLocation = shared; randomSleepTime = random; } public void Consume() { int sum = 0; for ( int count = 1; count <= 10; count++ ) { Thread.Sleep( randomSleepTime.Next( 1, 3001 ) ); sum += sharedLocation.Buffer; } Console.WriteLine("{0} read values totaling: {1}. Terminating {0}.", Thread.CurrentThread.Name, sum ); } } public class CircularBuffer { private int[] buffers = { -1, -1, -1 }; private int occupiedBufferCount = 0; private int readLocation = 0; private int writeLocation = 0; public int Buffer { get { lock ( this ) { if ( occupiedBufferCount == 0 ) { Console.Write( " All buffers empty. {0} waits.",Thread.CurrentThread.Name ); Monitor.Wait( this ); } int readValue = buffers[ readLocation ]; Console.Write( " {0} reads {1} ",Thread.CurrentThread.Name, buffers[ readLocation ] ); --occupiedBufferCount; readLocation = ( readLocation + 1 ) % buffers.Length; Console.Write( CreateStateOutput() ); Monitor.Pulse( this ); return readValue; } } set { lock ( this ) { if ( occupiedBufferCount == buffers.Length ) { Console.Write( " All buffers full. {0} waits.",Thread.CurrentThread.Name ); Monitor.Wait( this ); } buffers[ writeLocation ] = value; Console.Write( " {0} writes {1} ",Thread.CurrentThread.Name, buffers[ writeLocation ] ); ++occupiedBufferCount; writeLocation = ( writeLocation + 1 ) % buffers.Length; Console.Write( CreateStateOutput() ); Monitor.Pulse( this ); } } } public string CreateStateOutput() { string output = "(buffers occupied: " + occupiedBufferCount + ") buffers: "; for ( int i = 0; i < buffers.Length; i++ ) output += " " + string.Format( "{0,2}", buffers[ i ] ) + " "; output += " "; output += " "; for ( int i = 0; i < buffers.Length; i++ ) output += "---- "; output += " "; output += " "; for ( int i = 0; i < buffers.Length; i++ ) { if ( i == writeLocation && writeLocation == readLocation ) output += " WR "; else if ( i == writeLocation ) output += " W "; else if ( i == readLocation ) output += " R "; else output += " "; } output += " "; return output; } static void Main( string[] args ) { CircularBuffer shared = new CircularBuffer(); Random random = new Random(); Console.Write( shared.CreateStateOutput() ); Producer producer = new Producer( shared, random ); Consumer consumer = new Consumer( shared, random ); Thread producerThread = new Thread( new ThreadStart( producer.Produce ) ); producerThread.Name = "Producer"; Thread consumerThread = new Thread( new ThreadStart( consumer.Consume ) ); consumerThread.Name = "Consumer"; producerThread.Start(); consumerThread.Start(); } } [/csharp]

Producer and comsumer in a synchronized buffer

/*
Code revised from Book published by
(C) Copyright 1992-2006 by Deitel & Associates, Inc. and
Pearson Education, Inc. All Rights Reserved.

*/

using System;
using System.Threading;

public class SynchronizedBuffer
{
private int buffer = -1;

private int occupiedBufferCount = 0;

public int Buffer
{
get
{
Monitor.Enter( this );

if ( occupiedBufferCount == 0 )
{
Console.WriteLine(Thread.CurrentThread.Name + ” tries to read.” );
DisplayState( “Buffer empty. ” +Thread.CurrentThread.Name + ” waits.” );
Monitor.Wait( this );
}
–occupiedBufferCount;

DisplayState( Thread.CurrentThread.Name + ” reads ” + buffer );

Monitor.Pulse( this );
int bufferCopy = buffer;

Monitor.Exit( this );

return bufferCopy;
}
set
{
Monitor.Enter( this );
if ( occupiedBufferCount == 1 )
{
Console.WriteLine(Thread.CurrentThread.Name + ” tries to write.” );
DisplayState( “Buffer full. ” + Thread.CurrentThread.Name + ” waits.” );
Monitor.Wait( this );
}
buffer = value;

++occupiedBufferCount;

DisplayState( Thread.CurrentThread.Name + ” writes ” + buffer );
Monitor.Pulse( this );

Monitor.Exit( this );
}
}

public void DisplayState( string operation )
{
Console.WriteLine( “{0,-35}{1,-9}{2}
“,operation, buffer, occupiedBufferCount );
}

static void Main( string[] args )
{
SynchronizedBuffer shared = new SynchronizedBuffer();
Random random = new Random();

Console.WriteLine( “{0,-35}{1,-9}{2}
“,”Operation”, “Buffer”, “Occupied Count” );
shared.DisplayState( “Initial state” );

Producer producer = new Producer( shared, random );
Consumer consumer = new Consumer( shared, random );

Thread producerThread = new Thread( new ThreadStart( producer.Produce ) );
producerThread.Name = “Producer”;

Thread consumerThread = new Thread( new ThreadStart( consumer.Consume ) );
consumerThread.Name = “Consumer”;

producerThread.Start();
consumerThread.Start();
}
}

public class Consumer
{
private SynchronizedBuffer sharedLocation;
private Random randomSleepTime;

public Consumer( SynchronizedBuffer shared, Random random )
{
sharedLocation = shared;
randomSleepTime = random;
}

public void Consume()
{
int sum = 0;

for ( int count = 1; count <= 10; count++ ) { Thread.Sleep( randomSleepTime.Next( 1, 1001 ) ); sum += sharedLocation.Buffer; } Console.WriteLine("{0} read values totaling: {1}. Terminating {0}.",Thread.CurrentThread.Name, sum ); } } public class Producer { private SynchronizedBuffer sharedLocation; private Random randomSleepTime; public Producer( SynchronizedBuffer shared, Random random ) { sharedLocation = shared; randomSleepTime = random; } public void Produce() { for ( int count = 1; count <= 10; count++ ) { Thread.Sleep( randomSleepTime.Next( 1, 1001 ) ); sharedLocation.Buffer = count; } Console.WriteLine( "{0} done producing. Terminating {0}.",Thread.CurrentThread.Name ); } } [/csharp]