Multithreading is not something I've done extensively in the past, but in my current project, I'm getting it by the snootful. So I'm going to note a few things that are useful for dealing with multiple threads, especially in a Winforms UI situation. Invoking from the form If you are trying to access an object owned by the form from a thread other than the form's thread, you need to use the Form.Invoke. Here's a sample: delegate void FormDelegate(Form form, object parm1, object parm2); void myMethod(Form form, object parm1, object parm2) { if (form.InvokeRequired) { FormDelegate d = new FormDelegate(myMethod); form.Invoke(d, new object[] { form, parm1, parm2 } ); } else { [do your working code here] } } Invoking with an asynchronous callback Use an asynchronous callback to execute a method on another thread. Here's how: namespace PracticalCoder { class Program { public delegate bool myDelegate(bool value); myDelegate theDelegate; static void Main(string[] args) { Program p = new Program(); p.theDelegate = new myDelegate(p.StartupMethod); IAsyncResult retVal = p.theDelegate.BeginInvoke( true, new AsyncCallback(p.EndMethod), p); Console.ReadLine(); } public bool StartupMethod(bool value) { return value; } public void EndMethod(IAsyncResult asyncResult) { bool result = theDelegate.EndInvoke(asyncResult); Console.WriteLine("result = " + result.ToString()); } } } Of course, you can just spawn a new thread directly, which is useful especially if you are going to have a background process that runs more or less continuously. Thread t = new Thread(new ThreadStart(myMethod)); t.Start(); Also, if you are going to use a ParameterizedThreadStart object in place of the ThreadStart object, the target method must be a static method. Thread t = new Thread( new ParameterizedThreadStart(myStaticMethod)); t.Start(); Locking If you are trying to access an object on two different threads, you will have to lock the object so that the object doesn't get changed on one thread in a way that will have a negative impact upon the process on the other thread. Here is a common way: lock (myCollection) { //[operate on myCollection] } The pattern above may cause a deadlock if you are in a situation where the object may already be locked, resulting in a deadlock. If you are in a situation where you are likely to have a deadlock using the method above, try this: object lockableObject = new object(); public void lockTest() { if (System.Threading.Monitor.TryEnter(lockableObject, 1000)) { //[do work here] Monitor.Exit(lockableObject); } } The TryEnter method has a parameter allowing a timeout value in milliseconds to be set. You can also put this into the condition of a while loop. If you can't lock the object you need directly, you may choose to use a separate object dedicated to locking for a given situation. For example: object criticalSection = new object(); List<string> myList = new List<string>(); public void lockTest2() { lock (criticalSection) { foreach (string str in myList) { Console.WriteLine(str); } } } If I can think of other things, well, I'll just post 'em later.