2015-11-29 51 views
5

https://msdn.microsoft.com/en-us/magazine/gg598924.aspx當前的SynchronizationContext可以爲null嗎?

這是一篇很棒的文章,我意識到所有細節都無法被覆蓋,因爲這基本上涉及粘貼.NET框架的源代碼。所以引用文字:

每個線程都有一個當前上下文。 如果「Current」爲空,那麼線程的當前上下文是 「new SynchronizationContext()」,按照慣例。

在另一方面,但是:

默認情況下,當前的SynchronizationContext在一個AWAIT 點捕獲,而這個的SynchronizationContext用於恢復 等待之後(更準確地說,它捕捉當前的SynchronizationContext ,除非它是空,在這種情況下,它捕獲當前 的TaskScheduler)

這兩個陳述幾乎相互矛盾,所以我認爲這是作者所做的一些簡化的結果(我對它很好)。

任何人都可以解釋這一點嗎? Code這可能有助於回答我的問題(查找syncCtx變量),這段代碼與第二個引號有關。

+0

這並不矛盾 - 同步上下文*可以*爲空 - 它只是爲連續處理的目的,沒有任務調度空同步上下文相當於'SynchronizationContext'。 「按約定」只是捕獲同步上下文的處理方式,它不是禁止空同步上下文的規則。至於代碼,它是公開可用的 - http://referencesource.microsoft.com/#mscorlib/system/threading/synchronizationcontext.cs,8b34a86241c7b423。 – Luaan

回答

1

相關一塊你要找的代碼是內部方法Task.SetContinuationForAwait內:

// First try getting the current synchronization context. 
// If the current context is really just the base SynchronizationContext type, 
// which is intended to be equivalent to not having a current SynchronizationContext at all, 
// then ignore it. This helps with performance by avoiding unnecessary posts and queueing 
// of work items, but more so it ensures that if code happens to publish the default context 
// as current, it won't prevent usage of a current task scheduler if there is one. 
var syncCtx = SynchronizationContext.CurrentNoFlow; 
if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext)) 
{ 
    tc = new SynchronizationContextAwaitTaskContinuation(
       syncCtx, continuationAction, flowExecutionContext, ref stackMark); 
} 
else 
{ 
    // If there was no SynchronizationContext, then try for the current scheduler. 
    // We only care about it if it's not the default. 
    var scheduler = TaskScheduler.InternalCurrent; 
    if (scheduler != null && scheduler != TaskScheduler.Default) 
    { 
     tc = new TaskSchedulerAwaitTaskContinuation(
       scheduler, continuationAction, flowExecutionContext, ref stackMark); 
    } 
} 

它實際上並兩次檢查,先來看看它是不是null,第二要確保它不是默認SynchronizationContext,我認爲這是關鍵點。

如果您打開控制檯應用程序並嘗試獲取SynchronizationContext.Current,您一定會看到它可能是null

class Program 
{ 
    public static void Main(string[] args) 
    { 
     Console.WriteLine(SynchronizationContext.Current == null ? "NoContext" : 
                    "Context!"); 
    } 
} 
+0

那麼我該如何理解_如果「Current」爲null,那麼線程的當前上下文是「new SynchronizationContext()」,按照慣例。現在我意識到作者可能意味着我的上一個問題中的第二個代碼片段:http://stackoverflow.com/questions/33867387/why-is-synchronizationcontext-checked-for-null – user4205580

+0

我不確定Stephan Cleary是什麼意思他寫道。也許他在談論'AsyncOperatonManager',它總是設置一個默認的'SynchronizationContext'。 –

+1

這是兩種不同的情況。較早的文章僅涉及'SynchronizationContext',它確實將'null'的約定視爲'新的SynchronizationContext',例如,用於EAP組件。等待定義自己的情況稍有不同。如果你想扭曲你的大腦,Toub有一篇關於更多背景的文章。 –

相關問題