Tasks - how to ensure the ContinueWith action is an STA thread?

Viewed 2985

I am trying to use tasks in a little .net 4.0 application (written using Visual Studio 2010 if that matters) that needs to work on Windows 2003 and use a WriteableBitmap with the palette parameter.

The code using said class must, therefore, be running as an STA thread to avoid it throwing an invalid cast exception (see here for why I need an STA thread if you are interested, but it is not the thrust of my question).

I, therefore, checked on Stack overflow and came across How to create a task (TPL) running a STA thread? and The current SynchronizationContext may not be used as a TaskScheduler - perfect, so now I know what to do, except...

Here's a little console application:

using System;
using System.Threading;
using System.Threading.Tasks;
namespace TaskPlayingConsoleApplication
{
    class Program
    {
        [STAThread]
        static void Main()
        {
            Console.WriteLine("Before Anything: " 
                + Thread.CurrentThread.GetApartmentState());

            SynchronizationContext.SetSynchronizationContext(
                new SynchronizationContext());
            var cts = new CancellationTokenSource();
            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            var task = Task.Factory.StartNew(
                () => Console.WriteLine(
                    "In task: " + Thread.CurrentThread.GetApartmentState()),
                cts.Token,
                TaskCreationOptions.None,
                scheduler);

            task.ContinueWith(t =>
                 Console.WriteLine(
                   "In continue: " + Thread.CurrentThread.GetApartmentState()),
                   scheduler);

            task.Wait();
        }
    }
}

And here is its output:

Before Anything: STA 
In task: STA 
In continue: MTA

What the!?! Yup, it is back to an MTA thread on the Action<Task> passed into the ContinueWith method.

I am passing the same scheduler into the task and the continue but somehow in the continue it seems to be being ignored.

I'm sure it is something stupid, so how would I make sure that my callback passed into the ContinueWith uses an STA thread?

1 Answers
Related