2013-03-03 9 views
7

Secondo http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspx, la parola chiave await è vietata all'interno di un blocco unsafe, menzionando solo "le difficoltà inerenti alla conservazione dei puntatori non gestiti". C'è una buona spiegazione disponibile su quali siano queste difficoltà?Perché l'attesa è vietata in sezioni non sicure?

+4

Che altro dettaglio vuoi? Non è possibile utilizzarlo in blocchi non sicuri. –

+0

@MitchWheat Ammetto che sto afferrando qui, ma forse OP sta cercando informazioni su cosa * significhi *. –

+1

Significa che non puoi usarlo lì! Anche con una spiegazione dettagliata, non sarai ancora in grado di usarlo lì. Forse l'OP dovrebbe spiegare il problema che stanno cercando di risolvere. –

risposta

7

Due cose fondamentali che devi sapere. Un metodo asincrono viene riscritto dal compilatore C# in una piccola classe con un nome non indicibile che avvolge una macchina a stati. Le variabili locali del metodo async diventano campi di quella classe.

Il codice non sicuro si basa molto spesso sulla possibilità di creare puntatori a variabili locali. L'istruzione corretta è, crea una variabile locale nascosta che il garbage collector può vedere e quindi aggiornare quando si verifica un garbage collection che sposta la matrice che viene riparata. La creazione di puntatori a variabili locali va bene, quelle variabili non sono soggette a essere mai spostate dal garbage collector. Lo stack di un thread si trova sempre in una posizione fissa nello spazio degli indirizzi di memoria virtuale.

Collegare i due e viene visualizzato il problema, una variabile locale può trasformarsi in un campo di una classe, un campo il cui indirizzo cambia quando si verifica un Garbage Collection. Improvvisamente trasformare codice non sicuro in codice di rottura.

Un frammento di codice che illustra il problema:

class Example { 
    int field; 
    unsafe void Method() { 
     int local = 42; 
     int* p = &local; // fine 
     int* q = &field; // CS0212 
    } 
} 

Il C# team potrebbe hanno fatto lo sforzo di analizzare attentamente i casi in cui il codice non sicuro è ancora a posto dopo la riscrittura. Ma alcuni casi non sono semplicemente risolvibili, come la dichiarazione fissa. Un sacco di lavoro per dare solo notizie deludenti al programmatore, spesso per un motivo sconcertante. La cosa più sensata da fare qui era dichiarare semplicemente i limiti non sicuri del codice.

+0

Questo ha senso. È un vero peccato che la macchina statale pertinente non possa essere semplicemente dichiarata "risolta" (eventualmente, suppongo) e fatta finita. Suppongo che la soluzione sia allocare esplicitamente le variabili di chiusura necessarie in una classe, correggere quella classe e fare riferimento a parti di essa in modo appropriato. Ma questo dimezza il vantaggio della stregoneria del riscrittore asincrono. È un peccato! –

Problemi correlati