This project is read-only.

Active Object Tutorial

This tutorial aims to teach you how to use the ActiveObject concurrency utilities that can be found in the DigitallyCreated.Utilities.Concurrency library.

An ActiveObject is an object whose logic run in a different thread. Inheriting from either BoolStopActiveObject or InterruptStopActiveObject enables you to very quickly create a class whose code runs in a separate thread, saving you from having to create all the boilerplate code such as creating and setting up a Thread object, setting up a Finished event, and writing a safe way to stop the code running in that Thread.

ActiveObject allows inheritors to simply provide the implementation for the Run method, and then clients can call Start to start the execution of Run, but in a different thread. When Run returns, ActiveObject fires the Stopped event, which allows clients to be notified of when the thread has completed its execution, which is useful in some cases, particularly in the UI when you want to update the UI when the ActiveObject has completed processing something asynchronously. Be aware that Stopped is fired on the ActiveObject's thread.

There are two types of ActiveObject, the BoolStopActiveObject and the InterruptStopActiveObject, which each implement a different method for signalling to the ActiveObject that it needs to stop executing.

BoolStopActiveObject

The BoolStopActiveObject uses a boolean flag to indicate that the logic currently running inside it has been asked to stop as soon as possible. Here's an example of it in use:

public class MyBoolStopActiveObject : BoolStopActiveObject
{
    public MyBoolStopActiveObject()
        : base("MyBoolStopActiveObject", true)
    {
    }

    protected override void Run()
    {
        while (StopRequested == false)
        {
            //Do work
        }
    }
}

The constructor calls the base constructor which sets the thread's name and makes it a background thread (the true second parameter). In the Run method, which is what is run by the internal ActiveObject thread, we do a loop, whereby each iteration a check against the protected property StopRequested is done. StopRequested is set when RequestStop (inherited from ActiveObject) is called. When StopRequested is true, Run returns and the internal thread will stop. Of course, when you check StopRequested is entirely up to you.

InterruptStopActiveObject

The InterruptStopActiveObject uses a thread interrupt (see Thread.Interrupt for more information) to signal that your ActiveObject thread needs to stop executing. Here is an example implementation:

public class MyInterruptStopActiveObject : InterruptStopActiveObject
{
    public MyInterruptStopActiveObject()
        : base("MyInterruptStopActiveObject", true)
    {
    }

    protected override void Run()
    {
        while (true)
        {
            //Do periodic work
            
            try {
                Thread.Sleep(1000);
            }
            catch (ThreadInterruptedException e)
            { 
                return; //Time to exit
            }
        }
    }
}

In the Run method, we catch any ThreadInterruptedException that could occur (in this instance, it could occur from the Thread.Sleep call) and return immediately, ending the ActiveObject's thread.

Using an ActiveObject

void Main()
{
    MyInterruptStopActiveObject activeObject = new MyInterruptStopActiveObject();
    activeObject.Stopped += OnActiveObjectStopped;
    activeObject.Start(); //Start activeObject's thread
    activeObject.RequestStop(); //Ask activeObject to stop
    activeObject.Join(); //Don't return until activeObject stops
}

public void OnActiveObjectStopped(object sender, EventArgs args)
{
    Console.WriteLine("Stopped");
}

Last edited Mar 9, 2010 at 11:43 AM by dchambers, version 1

Comments

No comments yet.