Desidero chiarire la risposta (corretta) di BJ Myers.
In C# un evento può essere pensato come un campo di tipo delegato - proprio come una proprietà può essere pensata come un campo del tipo di proprietà - e il valore di quel "campo" può essere nullo. Se siete nella spiacevole situazione di dover un gestore di eventi in corso di modifica su un thread mentre un altro thread sta tentando di invocarlo, è possibile ottenere in una situazione in cui:
if (this.SomeEvent != null)
this.SomeEvent(...);
non è threadsafe. Il valore potrebbe essere mutato in modo tale che non sia nullo prima del controllo, nullo dopo il controllo e il programma si blocchi.
Il modo usuale per rendere questo "thread-safe", e io uso il termine consigliato, è quello di copiare il valore su un locale e quindi testare il locale per null. Questo ha il vantaggio di non bloccarsi con un dereferenziamento nullo. Tuttavia, lo sviluppatore intelligente noterà che c'è ancora una gara!La sequenza può essere
gestore di eventi
- non nullo nella cache sul thread A
- gestore di eventi impostato nulla sul filo B
- Stato necessaria per gestore di eventi viene distrutto sul filo B
- gestore di eventi viene eseguito su thread A e dies orribly
Quindi, in questo senso, questo modello non è "thread safe". Se sei in questa sfortunata posizione , sei responsabile di assicurare che la logica di threading appropriata sia implementata in modo che ciò non avvenga. Puoi farlo come vuoi. Se vuoi i (discutibili) vantaggi di poter chiamare un gestore di eventi su un thread mentre muti l'evento su un altro thread, devi pagare per renderlo sicuro, o gestire bug di race condition.
Personalmente eviterei questa situazione come la peste, ma non sono abbastanza intelligente per scrivere il codice multithread corretto.
Ora, come per la domanda effettiva:
some_expression ?. ToString();
è lo stesso di
temp = some_expression
temp == null ? null : temp.ToString()
è il secondo codice "threadsafe" secondo te?
fonte
2016-03-04 01:37:06
Ci scusiamo, ma il tuo primo blocco di codice può essere perfettamente thread-safe, a seconda del contesto in cui viene utilizzato e della portata delle variabili coinvolte. –
@KenWhite - Penso che l'idea con il primo blocco sia che un altro thread può impostare la variabile su 'null' dopo il controllo ma prima che' .ToString() 'causi il fallimento del codice. Direi che non è thread-safe. – Enigmativity
@Enigmativity: il poster in particolare diceva che il blocco di codice era ** non thread-safe **, che non è un'istruzione accurata senza conoscere il contesto o l'ambito. Ho fatto notare che l'affermazione era imprecisa: è falso che il codice in quel blocco non sia definitivamente thread-safe. –