2014-12-30 20 views
5

Seguo principalmente lo schema IDisposable e per la maggior parte delle classi giustificato. Ma ReaderWriterLockSlim mi ha fatto dubitare della fattibilità dell'applicazione di tale modello. Tutto lo ReaderWriterLockSlim.Dispose fa chiudere alcuni handle di evento. Quindi, quanto è importante la classe Dispose con così poche risorse? In questo caso, non mi dispiacerebbe davvero se il GC dovesse aspettare un altro giro per finire i finalizzatori delle risorse non gestite.Quanto "usa e getta" è ReaderWriterLockSlim?

Le conseguenze per l'applicazione del modello IDisposable sono considerevoli, tuttavia, ogni classe che utilizza una classe usa e getta ora deve implementare anche IDisposable. Nel mio caso particolare, sto implementando un wrapper per HashSet. Non mi aspetto particolarmente il requisito di disporre di tale oggetto perché, accidentalmente, utilizza un sincronizzatore che lo fa.

Ci sono motivi per non violare lo schema monouso in questo caso? Mentre sono ansioso, non lo farei in pratica, perché la violazione della coerenza è molto peggio.

+0

Il tuo problema è che usi un blocco non statico con la stessa durata dei tuoi oggetti? –

+0

@NathanCooper - Approssimativamente, sì. Anche l'istanziazione di un blocco per ogni operazione di lettura/scrittura non è molto efficiente. Potrei usare 'Monitor', ma mi preoccupo per i convogli di blocco. – toplel32

+0

quindi stai leggendo o scrivendo qualcosa e non è statico? Quindi è una risorsa per ogni istanza. –

risposta

4

Il problema con gli handle di sistema non gestiti è che handles come from a limited supply. Il GC non è a conoscenza di ciò.

Il consumo di memoria puro di un handle non è così grande. Nient'altro che un oggetto nella memoria del kernel e probabilmente una voce nella tabella hash da qualche parte.

Avete ragione nel dire che non è sufficiente dire: "È necessario sempre smaltire tutti gli oggetti monouso". Quella regola è troppo semplice. For example the Task class does not need to be disposed. Se sai cosa stai facendo, puoi prendere una posizione più sciolta riguardo allo smaltimento. Tieni presente che non tutti i membri del team potrebbero comprendere questo punto (ora puoi lasciare un link a questa risposta nel codice sorgente ...).

Se sei sicuro di non perdere molte maniglie, puoi farlo tranquillamente. Tieni presente che in condizioni marginali (carico, bug, ...) potresti perdere più di quanto avevi previsto causando problemi di produzione.

1

Se questo campo è staticyou don't need to dispose of it, esso (righty) avrà la stessa durata della propria applicazione. Vedo che non lo è, lascia andare.

Il modo corretto di gestire un IDisposable è di eliminarlo. Penso che abbiamo bisogno di una buona ragione per non farlo.

Utilizzare un altro blocco:

Penso che la cosa migliore da fare è quella di utilizzare Monitor o in un altro blocco, che avrà il vantaggio di semplificare il codice pure. ConcurrentDictionary e altre classi quadro sembrano adottare questo approccio.

Siete preoccupati per la trasmissione convoglia, ma non sono sicuro che questo sia stato risolto anche da ReaderWriterLockSlim, l'unica vera soluzione è quella di contenere meno blocchi e tenerli per meno tempo.

Non smaltire:

questo ha bisogno di una giustificazione. Puoi dimostrare i benefici prestazionali necessari qui?

Se si dispone di alcuni di questi oggetti di lunga durata, bene, non tutti gli articoli monouso sono ugualmente pesanti (non è come lasciare un documento word aperto), probabilmente lo farai franca. Come è stato sottolineato, qual è il punto di smaltimento di tutti questi millisecondi prima che l'applicazione si chiuda comunque.Credo che il distruttore di un IDisposable sia destinato a gestire situazioni in cui l'oggetto non è disposto, sebbene non si possa essere sicuri di quando o anche se viene chiamato.

Se si ha una lunga esperienza con molti usi di breve durata di questa classe, tuttavia, si possono incontrare dei problemi. Stai preparando le tue ipotesi sull'uso del tuo codice, fai attenzione.

+0

Con "distruttore", intendi un finalizzatore? Questo probabilmente non è nemmeno necessario perché le risorse non gestite avranno i finalizzatori stessi, quindi faranno ciò che il metodo dispose avrebbe invocato. Capisco che 'ReaderWriterLockSlim' offre solo un vantaggio con molte operazioni di lettura densa, giusto? 'Monitor' probabilmente non sottoperformerà per quello che sto cercando di fare, ma voglio essere al sicuro in futuro. – toplel32

+0

I distruttori C# sono finalizzatori .NET. Ho fatto notare che lo fanno da soli, ... sto rimuovendo quel paragrafo. Prendere la decisione di non disporvi farà alcuni dei tuoi presupposti (renderà più complicato scrivere un'applicazione con una lunga vita che usa tonnellate di questi oggetti in un modo di vita breve. maniglie). Prenderei quella decisione in base alle reali necessità, piuttosto che alle prove future. –

+0

Sì, ho pensato che c'era qualche ambiguità da qualche parte. In poche parole, la cosa peggiore che può succedere è che il GC deve posticipare la pulizia delle risorse non gestite perché deve eseguire i finalizzatori. Per quanto riguarda la cottura in premessa, penso di poterla farla franca stavolta, poiché Hans ha spiegato che questo tipo di lezione non è realmente convenzionale da istanziare in qualsiasi momento, per non parlare di una moltitudine di volte. – toplel32