Reputation: 31
I want use an existing code using ThreadStatic for implementing a per thread singleton (like Transaction.Current)
However, it doesn't work with the async/await model running in a new Task. I know that since SynchronizationContext.Current is null, ThreadPoolTaskScheduler is used and the continuation can be in another thread.
For exemple, if i execute the following code :
Task.Factory.StartNew(async () =>
{
Debug.WriteLine("Start on thread {0}", Environment.CurrentManagedThreadId);
await Task.Delay(10);
Debug.WriteLine("Continue on thread {0}", Environment.CurrentManagedThreadId);
});
The result is :
Start on thread 5
Continue on thread 4
My singleton implementation is something like this :
[ThreadStatic]
private static long? _sessionIndex; // Immutable value
private static ConcurrentDictionary<long, ...> contexts;
public static ... Current
{
get {
return contexts[_sessionIndex ?? (_sessionIndex=Interlocked.Increment(..))];
}
}
Stephen Cleary propose another solution based on a "singleton per ExecutionContext" which works perfectly in a 4.5.1 context but doesn't work with the limited winrt platform (CallContext doesn't exist)
As a solution, i would try to force the continuation execution in the same thread than the main task to keep the ThreadStatic mechanism.
Implementing a TaskScheduler could be a solution but you can not manipule thread in winrt.
Perhaps with a specific SynchronizationContext but i don't found how. I'm afraid that is not possible.
Any idea ?
Upvotes: 3
Views: 580
Reputation: 457057
I have a couple types AsyncContext
and AsyncContextThread
in my AsyncEx library which define a single-threaded context. They provide a custom TaskScheduler
and SynchronizationContext
.
The AsyncContextThread
works by taking a task from the thread pool, installing a main loop, and keeping that task until all the asynchronous operations complete. A "return to the same thread" task scheduler / synchronization context must operate this way because there is no way to queue thread pool work to a specific thread.
Upvotes: 5