2015-03-30 12 views
8

Wenn ich einen Standard-CancellationToken erstelle ich im Debugger sehen kann, dass die CancellationToken ein CancellationTokenSource mit ihm verbunden hat, die im privaten m_source Feld gespeichert ist:Wie kann ein Standard (CancellationToken) einen entsprechenden CancellationTokenSource

Not null

Ich frage mich, wie das sein kann wie für Strukturen default Schlüsselwort "will return each member of the struct initialized to zero or null depending on whether they are value or reference types" und CancellationTokenSource ist ein Referenztyp.

CancellationToken hat 2 Konstrukteure haben, die dieses Feld jedoch setzen sie als default(CancellationToken) irrelevant sind nicht nennen Konstrukteuren und new CancellationToken() (was genau das gleiche Verhalten hat) kann parameterlos Konstrukteuren nicht keinen Konstruktor becuase structs nicht anrufen (yet).

Antwort

11

default(CancellationToken) erstellt einen CancellationToken, wobei m_sourcenull ist. Sie können sehen, dass durch den Wert dieser privaten Bereich mit Reflexion bekommen:

Console.WriteLine(typeof (CancellationToken). 
    GetField("m_source", BindingFlags.NonPublic | BindingFlags.Instance). 
    GetValue(default(CancellationToken)) ?? "null"); 

Ausgang:

null 

Sie können auch sehen, dass nur das entsprechende Feld im Debugger von pining:

null

Also, was passiert?

Der Debugger, um den Inhalt des CancellationToken anzuzeigen, greift auf seine Eigenschaften einzeln zu. Wenn die innere CancellationTokenSource ist null die WaitHandle Eigenschaft erstellt und setzt einen Standard CancellationTokenSource vor seiner WaitHandle Eigenschaft Delegieren:

public WaitHandle WaitHandle 
{ 
    get 
    { 
     if (m_source == null) 
     { 
      m_source = CancellationTokenSource.InternalGetStaticSource(false); 
     } 

     return m_source.WaitHandle; 
    } 
} 

Abschließend default(CancellationToken) und new CancellationToken eine leere Struktur schaffen, in dem m_sourcenull ist aber by looking at the struct in the debugger you are filling that field mit einem Standard-CancellationTokenSource Instanz das kann nicht abgebrochen werden.

+5

Ah, ein Klassiker [Heisenbug] (http://en.wikipedia.org/wiki/Heisenbug). –