Showing posts with label Threading. Show all posts
Showing posts with label Threading. Show all posts

Thursday, 10 July 2014

Six ways to initiate tasks on another thread in .NET

Over the years, Microsoft have provided us with multiple different ways to kick off tasks on a background thread in .NET. It can be rather bewildering to decide which one you ought to use. So here’s my very quick guide to the choices available. We’ll start with the ones that have been around the longest, and move on to the newer options.

Asynchronous Delegates

Since the beginning of .NET you have been able to take any delegate and call BeginInvoke on it to run that method asynchronously. If you don’t care about when it ends, it’s actually quite simple to do. Here we’ll call a method that takes a string:

Action<string> d = BackgroundTask;
d.BeginInvoke("BeginInvoke", null, null);

The BeginInvoke method also takes a callback parameter and some optional state. This allows us to get notification when the background task has completed. We call EndInvoke to get any return value and also to catch any exception thrown in our function. BeginInvoke also returns an IAsyncResult allowing us to check or wait for completion.

This model is called the Asynchronous Programming Model (APM). It is quite powerful, but is a fairly cumbersome programming model, and not particularly great if you want to chain asynchronous methods together as you end up with convoluted flow control over lots of callbacks, and find yourself needing to pass state around in awkward ways.

Thread Class

Another option that has been in .NET since the beginning is the Thread class. You can create a new Thread object, set up various properties such as the method to execute, thread name, and priority, and then start the thread.

var t = new Thread(BackgroundTask);
t.Name = "My Thread";
t.Priority = ThreadPriority.AboveNormal;
t.Start("Thread");
This may seem like the obvious choice if you need to run something on another thread, but it is actually overkill for most scenarios.

It’s better to let .NET manage the creation of threads rather than spinning them up yourself. I only tend to use this approach if I need a dedicated thread for a single task that is running for the lifetime of my application.

ThreadPool

The ThreadPool was introduced fairly early on in .NET (v1.1 I think) and provided an extremely simple way to request that your method be run on a thread from the thread pool. You just call QueueUserWorkItem and pass in your method and state. If there are free threads it will start immediately, otherwise it will be queued up. The disadvantage of this approach compared to the previous two is that it provides no mechanism for notification of when your task has finished. It’s up to you to report completion and catch exceptions.

ThreadPool.QueueUserWorkItem(BackgroundTask, "ThreadPool");

This technique has now really been superseded by the Task Parallel Library (see below), which does everything the ThreadPool class can do and much more. If you’re still using it, its time to learn TPL.

BackgroundWorker Component

The BackgroundWorker component was introduced in .NET 2 and is designed to make it really easy for developers to run a task on a background thread. It covers all the basics of reporting progress, cancellation, catching exceptions, and getting you back onto the UI thread so you can update the user interface.

You put the code for your background thread into the DoWork event handler of the background worker:

backgroundWorker1.DoWork += BackgroundWorker1OnDoWork;

and within that function you are able to report progress:

backgroundWorker1.ReportProgress(30, progressMessage);

You can also check if the user has requested cancellation with the BackgroundWorker.CancellationPending flag.

The BackgroundWorker provides a RunWorkerCompleted event that you can subscribe to and get hold of the results of the background task. It makes it easy to determine if you finished successfully, were cancelled, or if an exception that was thrown. The RunWorkerCompleted and ProgressChanged events will both fire on the UI thread, eliminating any need for you to get back onto that thread yourself.

BackgroundWorker is a great choice if you are using WinForms or WPF. My only one criticism of it is that it does tend to encourage people to put business logic into the code behind of their UI. But you don't have to use BackgroundWorker like that. You can create one in your ViewModel if you are doing MVVM, or you could make your DoWork event handler simply call directly into a business object.

Task Parallel Library (TPL)

The Task Parallel Library was introduced in .NET 4 as the new preferred way to initiate background tasks. It is a powerful model, supporting chaining tasks together, executing them in parallel, waiting on one or many tasks to complete, passing cancellation tokens around, and even controlling what thread they will run on.

In its simplest form, you can kick off a background task with TPL in much the same way that you kicked off a thread with the ThreadPool.

Task.Run(() => BackgroundTask("TPL"));

Unlike the ThreadPool though, we get back a Task object, allowing you to wait for completion, or specify another task to be run when this one completes. The TPL is extremely powerful, but there is a lot to learn, so make sure you check out the resources below for learning more.

C# 5 async await

The async and await keywords were introduced with C# 5 and .NET 4.5 and allow you to write synchronous looking code that actually runs asynchronously. It’s not actually an alternative to the TPL; it augments it and provides an easier programming model. You can call await on any method that returns a task, or if you need to call an existing synchronous method you can do that by using the TPL to turn it into a task:

await Task.Run(() => xdoc.Load("http://feeds.feedburner.com/soundcode"));

The  advantages are that this produces much easier to read code, and another really nice touch is that when you are on a UI thread and await a method, when control resumes you will be back on the UI thread again:

await Task.Run(() => xdoc.Load("http://feeds.feedburner.com/soundcode"));
label1.Text = "Done"; // we’re back on the UI thread!

This model also allows you to put one try…catch block around code that is running on multiple threads, which is not possible with the other models discussed. It is also now possible to use async and await with .NET 4 using the BCL Async Nuget Package.

Here’s a slightly longer example showing a button click event handler in a Windows Forms application that calls a couple of awaitable tasks, catches exceptions whatever thread its on and updates the GUI along the way:

private async void OnButtonAsyncAwaitClick(object sender, EventArgs e)
{
    const string state = "Async Await";
    this.Cursor = Cursors.WaitCursor;
    try
    {
        label1.Text = String.Format("{0} Started", state);
        await AwaitableBackgroundTask(state);
        label1.Text = String.Format("About to load XML"); 
        var xdoc = new XmlDocument();
        await Task.Run(() => xdoc.Load("http://feeds.feedburner.com/soundcode"));
        label1.Text = String.Format("{0} Done {1}", state, xdoc.FirstChild.Name);
    }
    catch (Exception ex)
    {
        label1.Text = ex.Message;
    }
    finally
    {
        this.Cursor = Cursors.Default;
    }
}

Learn More

Obviously I can’t fully explain how to use each of these approaches in a short blog post like this, but many of these programming models are covered in depth by some of my fellow Pluralsight Authors. I’d strongly recommend picking at least one of these technologies to master (TPL with async await would be my suggestion).

Thread and ThreadPool:

Asynchronous Delegates:

BackgroundWorker:

Task Parallel Library:

Async and Await

Tuesday, 5 July 2011

Test Resistant Code #5–Threading

I want to wrap up my test-resistant code series with one final type of code that proves hard to test, and that is multi-threaded code. We’ll just consider two scenarios, one that proves easy to test, another that proves very complex.

Separate out thread creation

A common mistake is to include the code that creates a thread (or queues a background worker) in the same class that contains the code for the actual work to be performed by the thread. This is a violation of “separation of concerns” In the following trivial example, the function we really need to unit test, DoStuff, is private, and the public interface is not helpful for unit testing.

public void BeginDoStuff()
{
    ThreadPool.QueueUserWorkItem((o) => DoStuff("hello world"));
}

private void DoStuff(string message)
{
    Console.WriteLine(message);
}

Fixing this is not hard. We separate the concerns by making the DoStuff method a public member of a different class, leaving the original class simply to manage the asynchronous calling and reporting of results (which you may find can be refactored into a more generic threading helper class).

Locks and race conditions

But what about locking? Consider a very simple circular buffer class I wrote for NAudio. In the normal use case, one thread writes bytes to it while another reads from it. Here’s the current code for the Read and Write methods (which I’m sure could be refactored down to something much shorter):

/// <summary>
/// Write data to the buffer
/// </summary>
/// <param name="data">Data to write</param>
/// <param name="offset">Offset into data</param>
/// <param name="count">Number of bytes to write</param>
/// <returns>number of bytes written</returns>
public int Write(byte[] data, int offset, int count)
{
    lock (lockObject)
    {
        int bytesWritten = 0;
        if (count > buffer.Length - this.byteCount)
        {
            count = buffer.Length - this.byteCount;
        }
        // write to end
        int writeToEnd = Math.Min(buffer.Length - writePosition, count);
        Array.Copy(data, offset, buffer, writePosition, writeToEnd);
        writePosition += writeToEnd;
        writePosition %= buffer.Length;
        bytesWritten += writeToEnd;
        if (bytesWritten < count)
        {
            // must have wrapped round. Write to start
            Array.Copy(data, offset + bytesWritten, buffer, writePosition, count - bytesWritten);
            writePosition += (count - bytesWritten);
            bytesWritten = count;
        }
        this.byteCount += bytesWritten;
        return bytesWritten;
    }
}

/// <summary>
/// Read from the buffer
/// </summary>
/// <param name="data">Buffer to read into</param>
/// <param name="offset">Offset into read buffer</param>
/// <param name="count">Bytes to read</param>
/// <returns>Number of bytes actually read</returns>
public int Read(byte[] data, int offset, int count)
{
    lock (lockObject)
    {
        if (count > byteCount)
        {
            count = byteCount;
        }
        int bytesRead = 0;
        int readToEnd = Math.Min(buffer.Length - readPosition, count);
        Array.Copy(buffer, readPosition, data, offset, readToEnd);
        bytesRead += readToEnd;
        readPosition += readToEnd;
        readPosition %= buffer.Length;

        if (bytesRead < count)
        {
            // must have wrapped round. Read from start
            Array.Copy(buffer, readPosition, data, offset + bytesRead, count - bytesRead);
            readPosition += (count - bytesRead);
            bytesRead = count;
        }

        byteCount -= bytesRead;
        return bytesRead;
    }
}

The fact that I take a lock for the entirety of both methods makes me confident that the internal state will not get corrupted by one thread calling Write while another calls Read; the threads simply have to take it in turns. But what if I had a clever idea for optimising this code that only involved me locking for part of the time. Maybe I want to do the Array.Copy’s outside the lock since they potentially take the longest. How could I write a unit test that ensured my code remained thread-safe?

Short of firing up two threads reading and writing with random sleep times inserted here and there, I’m not sure I know how best to prove the correctness of this type of code. Locking issues and race conditions can be some of the hardest to track down bugs. I once spent a couple of weeks locating a bug that only manifest itself on a dual processor system (back in the days when those were few and far between). The code had been thoroughly reviewed by all the top developers at the company and yet no one saw the problem.

Here’s another example, based on some code I saw in a product I worked on. A method kicks off two threads to do some long-running tasks and attempts to fire a finished event when both have completed. We want to ensure that the SetupFinished event always fires, and only fires once. You might be able to spot a race condition by examining the code, but how would we write a unit test to prove we had fixed it?

private volatile bool eventHasBeenRaised;

public void Init()
{    
    ThreadPool.QueueUserWorkItem((o) => Setup1());
    ThreadPool.QueueUserWorkItem((o) => Setup2());    
}

private void Setup1()
{
    Thread.Sleep(500);
    RaiseSetupFinishedEvent();
}

private void Setup2()
{
    Thread.Sleep(500);
    RaiseSetupFinishedEvent();
}

private void RaiseSetupFinishedEvent()
{
    if (!eventHasBeenRaised)
    {
        eventHasBeenRaised = true;
        SetupFinished(this, EventArgs.Empty);
    }
}

The only tool for .NET I have heard of that might begin to address this shortcoming is Microsoft CHESS. It seems a very promising tool although it seems to have stalled somewhat – the only integration is with VS2008; VS2010 is not supported. I’d love to hear of other tools or clever techniques for unit testing multi-threaded code effectively. I haven’t delved too much into the C# 5 async stuff yet, but I’d be interested to know how well it plays with unit tests.

Friday, 26 September 2008

Don't Repeat Your Threading Code

Often when writing Windows Forms applications I will need to perform a long-running action on a background thread. So I write some code that can kick a delegate off in another thread (probably using the ThreadPool) and then some more code that handles when the action has completed. Then there is the code that handles any exceptions that were raised during that background action. Then there is the code that marshals back to the GUI thread so I can actually update controls on the form. Then I often end up adding a framework for reporting progress, and for aborting the action.

The end result is that the actual code that implements the task at hand has been obscured by a huge pile of threading related lines of code. And very often this code gets replicated every time a new action that needs to run on a background thread is written.

So I decided to see how far I could go with a DRY approach - ("Don't Repeat Yourself"), and decided to create a base BackgroundAction class that would hide a lot of the heavy lifting.

The first step was to create an interface, IBackgroundAction. The key components are the Begin method, that starts the action, and the Finished event, which indicates that the action has finished (successfully or not). I also put in a basic Progress reporting mechanism, as well as a way to request a Cancel of the action.

public interface IBackgroundAction
{
    void Begin();
    event EventHandler<ActionFinishedEventArgs> Finished;
    event EventHandler<ProgressEventArgs> Progress;
    void Cancel();
    ActionState State { get; }
}

public class ActionFinishedEventArgs : EventArgs
{
    public ActionState State { get; set; }
    public Exception Exception { get; set; }
}

public class ProgressEventArgs : EventArgs
{
    public string Message { get; set; }
}

public enum ActionState
{
    None,
    InProgress,
    Success,
    Cancelled,
    Error
}

The next step was to create an abstract base class, BackgroundAction that implements the interface, and does as much of the work as is possible:

abstract class BackgroundAction : IBackgroundAction
{
    protected volatile bool cancel;
    ActionState state = ActionState.None;
    public event EventHandler<ActionFinishedEventArgs> Finished;
    public event EventHandler<ProgressEventArgs> Progress;

    public void Begin()
    {
        if (state != ActionState.None)
        {
            throw new InvalidOperationException("Begin should only be called once");
        }
        state = ActionState.InProgress;
        ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
    }

    void ThreadProc(object state)
    {
        try
        {
            PerformBackgroundAction();
            state = cancel ? ActionState.Cancelled : ActionState.Success;
            ReportFinished();
        }
        catch (Exception e)
        {
            state = ActionState.Error;
            if (Finished != null)
            {
                Finished(this, new ActionFinishedEventArgs() { State = State, Exception = e });
            }
        }
    }

    protected abstract void PerformBackgroundAction();

    public void Cancel()
    {
        cancel = true;
    }

    public ActionState State
    {
        get { return state; }
    }

    void ReportFinished()
    {
        if (Finished != null)
        {
            Finished(this, new ActionFinishedEventArgs() { State = state });
        }
    }

    protected void ReportProgress(string message, params object[] args)
    {
        if (Progress != null)
        {
            Progress(this, new ProgressEventArgs() { Message = String.Format(message, args) });
        }
    }
}

This class manages the launching of the background action and the reporting of its completion (whether successful or not). It also includes a ReportProgress function as a helper for the concrete class to use.

Moving all this threading related code into a base class means that whenever we create a new action, the code we write is much cleaner, and only has the additional concerns of cancel checking and reporting progress. Here's an example from the project I was trying this out on. All I had to do was override the PerformBackgroundAction function to do the task at hand...

class DeserializeAllAction : BackgroundAction
{
    IEnumerable<BinarySearchResult> searchResults;

    public DeserializeAllAction(IEnumerable<BinarySearchResult> 
                                searchResults)
    {
        this.searchResults = searchResults;
    }

    protected override void PerformBackgroundAction()
    {
        ReportProgress("Preparing to deserialize");
        int count = 0;
        foreach (BinarySearchResult result in searchResults)
        {
            if (cancel)
            {
                break;
            }
            if (++count % 10 == 0)
            {
                ReportProgress("Deserialized {0}", count);
            }
            result.Deserialize();
        }
    }
}

The next step was to create a Progress Form that could take any IBackgroundAction, and run it, while showing progress updates and allowing the user to cancel. Here's a simple implementation:

public partial class ProgressForm : Form
{
    IBackgroundAction backgroundAction;
    bool finished;
    
    public ProgressForm(string title, IBackgroundAction 
                        backgroundAction)
    {
        this.backgroundAction = backgroundAction;
        backgroundAction.Finished += new 
            EventHandler<ActionFinishedEventArgs>
               (backgroundAction_Finished);
        backgroundAction.Progress += new 
            EventHandler<ProgressEventArgs>
                (backgroundAction_Progress);
        InitializeComponent();
        this.FormClosing += new 
            FormClosingEventHandler(ProgressForm_FormClosing);
        this.labelProgressMessage.Text = String.Empty;
        this.Text = title;
    }

    void ProgressForm_FormClosing(object sender, 
       FormClosingEventArgs e)
    {
        if (!finished)
        {
            backgroundAction.Cancel();
            buttonCancel.Enabled = false;
            e.Cancel = true;
        }
    }

    void backgroundAction_Progress(object sender, 
       ProgressEventArgs e)
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new 
               EventHandler<ProgressEventArgs>
                  (backgroundAction_Progress), sender, e);
            return;
        }
        labelProgressMessage.Text = e.Message;
    }

    void backgroundAction_Finished(object sender, 
        ActionFinishedEventArgs e)
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new  
               EventHandler<ActionFinishedEventArgs>
                  (backgroundAction_Finished), sender, e);
            return;
        }
        if(e.State == ActionState.Error)
        {
            MessageBox.Show(this, e.Exception.Message,
                this.Title,
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
        finished = true;
        this.Close();
    }

    private void ProgressForm_Load(object sender, EventArgs e)
    {
        backgroundAction.Begin();
    }
}

Now the code to create and run my background action becomes trivial:

private void buttonDeserializeAll_Click(object sender, EventArgs e)
{
    DeserializeAllAction deserializer = new DeserializeAllAction(searchResults);
    ProgressForm progressForm = new ProgressForm("Deserializing all results", deserializer);
    progressForm.ShowDialog(this);
}

So I was quite pleased with what I had achieved, but I started wondering whether I could take things one step further. In our PerformBackgroundAction function, we still have to perform periodic checks for cancellation and progress updates. These can't be moved down into the base class because it doesn't know when it can check and what it can report.

But then I considered the fact that most long-running background operations are in fact working their way through some kind of list. If I could insert the progress reporting and cancel checking into the enumerator, the PerformBackgroundAction function could focus entirely on doing the action at hand.

Here's my ProgressEnumerator class that injects progress reporting and cancel checking into any IEnumerable type. It calls back once every time round the loop, allowing a progress message to be emitted (if required), and allowing cancellation to be signalled (by returning true from the callback):

delegate bool ProgressCallback<T>(T value, int count);

class ProgressEnumerator<T>
{
    public static IEnumerable<T> Create(IEnumerable<T> items, ProgressCallback<T> callback)
    {
        ProgressEnumerator<T> enumerator = new ProgressEnumerator<T>(items, callback);
        return enumerator.Items;
    }

    IEnumerable<T> items;
    ProgressCallback<T> callback;
    int count;

    public ProgressEnumerator(IEnumerable<T> items, ProgressCallback<T> callback)
    {
        this.items = items;
        this.callback = callback;
        count = 0;
    }

    public IEnumerable<T> Items
    {
        get
        {
            foreach (T item in items)
            {
                if(callback(item,++count))
                    break;
                yield return item;
            }
        }
    }
}

Now we can revisit our PerformBackgroundAction function and remove the progress reporting and cancellation checking from inside the foreach loop, and moving it out into a separate function.

protected override void PerformBackgroundAction()
{
    ReportProgress("Preparing to deserialize");
    foreach (BinarySearchResult result in 
        ProgressEnumerator<BinarySearchResult>.Create(searchResults,ProgressCallback))
    {
        result.Deserialize();
    }
}

bool ProgressCallback(BinarySearchResult result, int count)
{
    if (count % 10 == 0)
    {
        ReportProgress("Deserialized {0}", count);
    }
    return cancel;
}

Finally I have achieved what I wanted. The GUI code that launches the background action is simple, and the code that performs the background action - the real 'business logic' - is unencumbered with threading related noise.

I'm sure that both my BackgroundAction and ProgressEnumerator classes have lots of ways in which they can be improved or streamlined further. Feel free to critique them in the comments.