WinRT上下文中与Async的线程关联

时间:2014-01-12 21:39:22

标签: c# asynchronous async-await winrt-async

我想使用ThreadStatic的现有代码来实现每个线程的单例(如Transaction.Current)

但是,它不适用于在新任务中运行的async / await模型。我知道,由于SynchronizationContext.Current为null,因此使用了ThreadPoolTask​​Scheduler,并且继续可以在另一个线程中。

例如,如果我执行以下代码:

Task.Factory.StartNew(async () =>
{                    
   Debug.WriteLine("Start on thread {0}", Environment.CurrentManagedThreadId);
   await Task.Delay(10);
   Debug.WriteLine("Continue on thread {0}", Environment.CurrentManagedThreadId);
});

结果是:

从线程5开始

继续第4课

我的单例实现是这样的:

[ThreadStatic]
private static long? _sessionIndex; // Immutable value
private static ConcurrentDictionary<long, ...> contexts;
public static ... Current 
{
  get { 
    return contexts[_sessionIndex ?? (_sessionIndex=Interlocked.Increment(..))];
  }
}

Stephen Cleary基于“每个ExecutionContext的单例”提出another solution,它在4.5.1上下文中完美运行但不适用于有限的winrt平台(CallContext不存在)

作为一个解决方案,我会尝试在与主任务相同的线程中强制继续执行,以保持ThreadStatic机制。

实现TaskScheduler可能是一个解决方案,但你不能在winrt中操纵线程。

也许使用特定的SynchronizationContext但我没有找到。 我担心这是不可能的。

有什么想法吗?

1 个答案:

答案 0 :(得分:5)

我的AsyncContext and AsyncContextThread中有几种类型AsyncEx library,用于定义单线程上下文。他们提供自定义TaskSchedulerSynchronizationContext

AsyncContextThread通过从线程池中获取任务,安装主循环并保持该任务直到所有异步操作完成为止。 “返回同一个线程”任务调度程序/同步上下文必须以这种方式运行,因为无法将线程池工作排队到特定线程。