Executors Framework

From Unify Community Wiki
Revision as of 19:17, 12 August 2010 by Magwo (Talk | contribs)

Jump to: navigation, search

Author: Magnus Wolffelt

Contents

Description

This is a small framework designed to assist in the usage of multiple threads in a C#/.Net program. Multi-threading is a very complex subject, and it's really hard to write bug-free multi-threaded code - hence the need for frameworks that make it a little easier.

The way this works is with the concepts of "Executors", "Callables" and "Futures". An executor is an object that consumes Callable objects (work tasks), and returns Future objects. These Future objects have a generic parameter which is the result type of the computation. The Future objects can also be polled for completion, or they can be requsted to return the result - which blocks the calling thread until the result has been computed.

While similar to the AsyncOperation provided by Unity, this concept is primarily inspired by the Java standard library, which features an extensive collection of implementations for this purpose.

Why?

The primary advantage over AsyncOperation is that these tasks are executed by an explicitly instantiated executor, which means one can easily change the way in which async tasks are executed. For example, simply exchange the SingleThreadExecutor instantiation for an ImmediateExecutor, and you are no longer using multi-threading at all, but your other code remains exactly the same as before.

Usage

To execute tasks, you need an executor: <csharp>

   IExecutor myExecutor = new ImmediateExecutor(); // or new SingleThreadExecutor() for example

</csharp>

Then you submit tasks: <csharp>

   Future<int> myFuture1 = myExecutor.Submit(new MultiplyIntsTask(5, 7));
   Future<int> myFuture2 = myExecutor.Submit(new MultiplyIntsTask(5, 12));

</csharp>

And then you can either poll: <csharp>

   if(myFuture1.IsDone) { int myResult = myFuture1.GetResult(); }

</csharp>

or... get the result directly (blocking call): <csharp>

   int myResult = myFuture1.GetResult(); // Blocks until result is ready

</csharp>


The MultiplyIntsTask looks like this: <csharp>

   class MultiplyIntsTask : ICallable<int> {
     int a;
     int b;
     public MultiplyIntsTask(int a, int b) {
       this.a = a;
       this.b = b;
     }
     public int Call() {
       return a * b;
     }
   }

</csharp>

This particular task is very fast and really not a good candidate for threaded processing. Consider this an illustrative example only.

Code

There are 8 files:

  • #IExecutor.cs
  • ICallable.cs
  • Future.cs
  • ImmediateExecutor.cs
  • SingleThreadExecutor.cs
  • Task.cs
  • ExecutionException.cs
  • ExecutorTester.cs. (Not required for usage)

IExecutor.cs

Foo.

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox