我正在尝试在一个小的.net 4.0应用程序中使用tasks(使用Visual Studio 2010编写),该应用程序需要在Windows 2003上工作并使用带调色板参数的WriteableBitmap。
因此,使用该类的代码必须运行为STA线程,以避免它抛出无效转换异常(如果您有兴趣,请参见这里,但这不是我的问题的关键所在)。
因此,我在Stack overflow上查找,并发现了如何创建运行STA线程的任务(TPL)?和当前的同步上下文可能不能用作任务调度程序 - 完美,所以现在我知道该怎么做了,但是...
这里有一个小型控制台应用程序:
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();
}
}
}
以下是它的输出结果:
Before Anything: STA
In task: STA
In continue: MTA
天哪!?!?没错,这是关于传递给ContinueWith
方法的Action<Task>
的MTA线程。
我将相同的调度程序传递到任务和继续中,但在继续中似乎被忽略了。
我确信这是一些愚蠢的事情,那么如何确保我的回调传递给ContinueWith使用STA线程?
SynchronizationContext
的默认实现使用 .NET 线程池。线程池线程默认为 MTA。 - Mike Zboray