Я хочу использовать существующий код с использованием ThreadStatic для реализации синглтона для каждого потока (например, Transaction.Current)
Однако это не работает с моделью async/await, работающей в новой задаче. Я знаю, что поскольку SynchronizationContext.Current имеет значение null, используется ThreadPoolTaskScheduler и продолжение может быть в другом потоке.
Например, если я выполню следующий код:
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(..))];
}
}
Стивен Клири предлагает еще одно решение, основанное на ExecutionContext", который отлично работает в контексте 4.5.1, но не работает с ограниченной платформой winrt (CallContext не существует)
В качестве решения я бы попытался заставить выполнение продолжения в том же потоке, что и основная задача, чтобы сохранить механизм ThreadStatic.
Реализация TaskScheduler может быть решением, но вы не можете манипулировать потоком в winrt.
Возможно, с определенным SynchronizationContext, но я не нашел, как это сделать. Боюсь, это невозможно.
Есть идеи ?