Questa correzione del Resharper per l’avviso di chiusura eliminata ha senso?

Sto lavorando per eliminare alcuni avvisi da un’analisi del codice statico. In un caso specifico non è stato effettuato alcun smaltimento su ManualResetEvent .

Il codice in questione esegue un Func sul thread principale e blocca il thread chiamante per un determinato numero di millisecondi. Mi rendo conto che sembra una cosa strana da fare, ma è fuori dallo scopo di questa domanda, quindi abbi pazienza con me.

Supponiamo che aggiungo un’istruzione using modo:

 object result = null; using (var completedEvent = new ManualResetEvent(false)) { _dispatcher.BeginInvoke((Action)(() => { result = someFunc; completedEvent.Set(); // Here be dragons! })); completedEvent.WaitOne(timeoutMilliseconds); return result; } 

Ora, mi rendo conto che questo potrebbe causare problemi. Mi capita anche di usare Resharper e mi avverte con il messaggio “Accesso alla chiusura eliminata”.

Il ricercatore propone di risolvere questo problema cambiando la riga incriminata in:

     if (completedEvent != null) { completedEvent.Set(); } 

    Ora, la soluzione proposta mi lascia perplesso. In circostanze normali, non ci sarebbe alcuna ragione per cui una variabile verrebbe impostata su null da un’istruzione using . Sono presenti alcuni dettagli di implementazione per le chiusure in .NET che garantirebbero la variabile come null dopo che la variabile che è stata chiusa viene eliminata?

    Come domanda bonus, quale sarebbe una buona soluzione al problema di smaltire ManualResetEvent ?

    Stai mescolando le “soluzioni rapide” e “azione contestuale” di ReSharper. Quando ReSharper propone di aggiustare qualcosa, molto probabilmente vedresti una lampadina lì. Non vedi una lampadina qui, perché non ci sono soluzioni rapide a questo avviso.

    Ma a parte le correzioni rapide, ReSharper dispone anche di “azioni contestuali”, dove può svolgere alcune attività di routine per te (pensa a loro come a piccoli refactoring). Quando ReSharper ha un’azione di contesto per un codice sotto il cursore, ti mostrerà una scelta. Qui vedi un’azione di contesto chiamata “Controlla se qualcosa non è nullo”. Non ha alcuna relazione con un avvertimento e non esiste alcuna convenzione che dopo lo smaltimento di una variabile venga impostata su null.

    Inoltre, quando premi Alt-Enter, vedrai una lampadina barrata per dare l’impressione che ReSharper non suggerisca alcuna soluzione rapida per questo avviso, ma può disabilitarlo con i commenti. In effetti, questo è l’unico modo per far sparire facilmente questo avviso. Ma avrei riscritto invece questo pezzo di codice.

    Mi sono imbattuto esattamente in questo solo poche ore fa.

    È un falso allarme. R # non capisce che l’esecuzione si bloccherà fino a quando l’evento non sarà impostato, anche se ciò rimanda lo smaltimento al momento giusto.

    IMO è una buona soluzione. Ignora semplicemente R #.

    Suggerisci catching a ObjectDisposedException quando chiami completedEvent.Set() nel caso in cui il timeout sia scaduto e l’evento sia stato eliminato. Non penso che questo impedirà l’avviso R #, ma è sicuro.

    Penso che tu debba controllare su null, inoltre devi prendere questa eccezione. Immagina cosa succederà se someFunc più di timeoutMilliseconds .