Windows Store Apps: Threads to Tasks
Posted on June 21, 2013
If you’re updating an old .NET code base to a Windows Store app, you may notice that the Thread class is no longer available. Instead, we have the more sophisticated Task. If you have a lot of Thread usage in your old code, you may find a re-write of the threading code to be a large task (sorry).
Here’s some code that you can use in place of the missing Thread class. This uses Tasks under the hood:
using System; using System.Threading; using System.Threading.Tasks; namespace WindowsStore.Compatibility { public class Thread { public Thread(ThreadStart start) { if (start == null) throw new ArgumentNullException("start"); action = new Action(start); } public Thread(ParameterizedThreadStart start) { if (start == null) throw new ArgumentNullException("start"); parameterizedAction = new Action
This handles the basics: starting a thread with or without parameters, waiting on a thread (Join), and pausing the sleeping the current thread. There are just a couple of differences.
Abort
In the traditional .NET framework, Thread.Abort throws a ThreadAbortException in the thread procedure, non-gracefully terminating the thread. Tasks introduce a cooperative cancellation mechanism that allows the thread to terminate gracefully when it is at a convenient stopping place. Cooperative means that the thread procedure must have a means of periodically checking whether it should terminate. This is done with a CancellationToken. Thus, we must provide this token to the thread procedure. I’ve redefined the ThreadStart and ParameterizedThreadStart to add the token as an extra parameter. This means a minor change in your thread procedure declaration. If you don’t need support for Thread.Abort in your code migration, you can just redefine these as:
public delegate void ThreadStart(); public delegate void ParameterizedThreadStart(object o);
The above definitions match the original .NET delegate types, so your original Thread-based code can compile with no changes.
If you do require Abort, use the earlier delegate definitions with the CancellationToken parameter. In your thread procedure, implement the abort by checking token.IsCancellationRequested. If true, simply return from the thread procedure to end the thread. For example:
Thread t = new Thread(MyThreadProc); t.Start(); private void MyThreadProc(CancellationToken cancelToken) { while(true) { if (cancelToken.IsCancellationRequested) return; // do some useful work here } }
And that’s all there is to it!
Got something to say?