Is my multithreaded form code correct? The basic idea is this:

There are two buttons: a DoWork button and a Cancel button.

The DoWork button should launch a thread to do some work, unless that thread was already launched and not canceled.

The Cancel button should cancel the worker thread, if it's running.

Please ignore the fact that it calls Thread.Abort() for the moment, that is a separate issue that I will address later.

Also, how does one generally show the correctness of one's own multithreaded code?  It seems much more difficult to debug.

Here's the code:

    private Thread m_WorkingThread;
    private bool m_finishedWorking;

    public Form()
    {
        InitializeComponent(); // initialize all the form controls.
        m_WorkingThread = null;
        m_finishedWorking = false;
    }

    private void bDoWork_Click(object sender, EventArgs e)
    {            
        if (m_WorkingThread != null)
            if(m_WorkingThread.IsAlive  || m_finishedWorking)
                return;

        ThreadStart ts = new ThreadStart(DoWork);
        Thread t = new Thread(ts);
        t.Start();
        m_WorkingThread = t;

    }
    private void bCancel_Click(object sender, EventArgs e)
    {
        AbortThread(m_WorkingThread);
        m_finishedWorking = false;
    }
    private void AbortThread(Thread t)
    {
        if (t != null)
            if (t.IsAlive)
                t.Abort();
    }
    private void DoWork()
    {
        // do some work here, maybe using Invokes / BeginInvokes to update any controls.

        m_finishedWorking = true;
    }
Have you considered using BackgroundWorker? It might save you some trouble.

However, it does use ThreadPool and you are better to create your own threads if you have any of the following requirements:


You require a foreground thread.
You require a thread to have a particular priority.
You have tasks that cause the thread to block for long periods of time. The thread pool has a maximum number of threads, so a large number of blocked thread pool threads might prevent tasks from starting.
You need to place threads into a single-threaded apartment. All ThreadPool threads are in the multithreaded apartment.
You need to have a stable identity associated with the thread, or to dedicate a thread to a task.


I add my comment to the answer of "Peter K." here as it seemed to please you.


  Mutex is a bit overkill as it works
  across multiple processes. One should
  use locks (i.e. Monitor) when there is
  no need to synchronize across
  processes. Anyway, I don't see here
  any need for the locks assuming that
  the bDoWork_Click() is always called
  from the UI thread. It only creates a
  new thread if the existing thread is
  not alive. However, the resources used
  by DoWork() must be protected with
  locks if they are shared with other
  threads.