static void

.Net Threading

This is the low-level threading to support async operations. The framework classes provide higher level APIs (eg Begin/End Async). From .net 4.5, when almost everything can be made easily awaitable.

Simple Threads

Thread t = new Thread(SlowMethod); //ThreadStart delegate (no parameters)
t.Start(); //start it
t.Join(); //wait for it to finish
Debug.WriteLine(Thread.CurrentThread.Name + " Child threads finished");

//ParameterizedThreadStart delegate (one "object" parameter)
Thread tp = new Thread(SlowMethodWithObjectParameter);
tp.Start(1000); //pass in object start
tp.Join();

//Strongly typed with a delegate
Thread td = new Thread(delegate() { SlowMethodWithParameter(2000); });
td.Start(); //start the delegate which starts the method
td.Join();

ThreadPool

//optimize with ThreadPool (WaitCallback must have one "object" parameter)
ThreadPool.QueueUserWorkItem(SlowMethodWithObjectParameter);

Async delegates

//simple async delegate
//private delegate string WorkerDelegate(string s);
//private string Worker(string s) { return s.ToUpper(); }
WorkerDelegate method = Worker;
IAsyncResult ar = method.BeginInvoke("test", null, null);
// do other stuff
string uppercased = method.EndInvoke(ar);
// ** or **
method.BeginInvoke("test", DoneCallback, null);
/*static void DoneCallback(IAsyncResult ar)
{Debug.WriteLine(((WorkerDelegate)ar.AsyncState).EndInvoke(ar));}*/

Threading notes

Timers

System.Threading.Timer tm = new System.Threading.Timer(new TimerCallback(Tick), "tock", 0, 0);
//startTime - 0 to start immediately, period- 0 to execute once
 
System.Timers.Timer tm2 = new System.Timers.Timer(1000);
tm2.Elapsed += delegate { Debug.WriteLine("Tock"); };
tm2.Enabled = true;
//do something
tm2.Enabled = false; //stop it
 
//remember System.Windows.Forms.Timer only works in WinForms and is actually singlethreaded

Thread Sync

msdn

Asynchronous Patterns

The async patterns are wait (waithandle or EndInvoke), polling (IsCompleted) and Callback

protected void Main()
{
    Literal1.Text = "Load= " + Thread.CurrentThread.ManagedThreadId;
    Literal2.Text = "Begin/End= " + TestAsync();
    Literal3.Text = "Load= " + Thread.CurrentThread.ManagedThreadId;
    Literal4.Text = "Polling= " + TestAsyncPolling();
    Literal5.Text = "Load= " + Thread.CurrentThread.ManagedThreadId;
    Literal6.Text = "WaitHandle= " + TestAsyncWaitHandle();
    TestAsyncCallback();
    Literal7.Text = "Callback= " + _result;
    Literal8.Text = "Load= " + Thread.CurrentThread.ManagedThreadId;
}
 
//a normal method doing something slow
public int SlowMethod(int sleep)
{
    Thread.Sleep(sleep);
    return Thread.CurrentThread.ManagedThreadId;
}
 
//delegate with same signature
public delegate int SlowMethodDelegate(int sleep);
 
public int TestAsync()
{
    SlowMethodDelegate dg = SlowMethod; //create delegate
    IAsyncResult ar = dg.BeginInvoke(2000, null, null); //start
    Thread.Sleep(1000); //possibly do other work
    return dg.EndInvoke(ar); //block until done
}
 
public int TestAsyncPolling()
{
    SlowMethodDelegate dg = SlowMethod; //create delegate
    IAsyncResult ar = dg.BeginInvoke(2000, null, null); //start
    while (!ar.IsCompleted)
    {
        Thread.Sleep(500); //possibly do other work
    }
    return dg.EndInvoke(ar);
}
 
public int TestAsyncWaitHandle()
{
    SlowMethodDelegate dg = SlowMethod; //create delegate
    IAsyncResult ar = dg.BeginInvoke(2000, null, null); //start
    Thread.Sleep(500); //possibly do other work
    ar.AsyncWaitHandle.WaitOne(); //block until done
    return dg.EndInvoke(ar);
}
 
private int _result;
public void TestAsyncCallback()
{
    SlowMethodDelegate dg = SlowMethod; //create delegate
    IAsyncResult ar = dg.BeginInvoke(2000, CallBack, dg); //start
    //end
}
private void CallBack(IAsyncResult ar)
{
    SlowMethodDelegate dg = (SlowMethodDelegate) ar.AsyncState; //our delegate back
    _result = dg.EndInvoke(ar);
}