Domanda

Comprendo la funzione principale della parola chiave di blocco di MSDN

Istruzione lock (riferimento C#)

La parola chiave di blocco segna un blocco di istruzione come sezione critica ottenendo il blocco di esclusione reciproca per un determinato oggetto, eseguendo un'istruzione e quindi rilasciando il blocco.

Quando dovrebbe essere utilizzata la serratura?

Ad esempio, ha senso con le applicazioni multi-thread perché protegge i dati.Ma è necessario quando l'applicazione non crea altri thread?

Ci sono problemi di prestazioni con l'utilizzo del blocco?

Ho appena ereditato un'applicazione che utilizza il blocco ovunque, ed è a thread singolo e voglio sapere se dovrei lasciarli, sono necessari?

Tieni presente che questa è più una domanda di conoscenza generale, la velocità dell'applicazione va bene, voglio sapere se è un buon modello di progettazione da seguire in futuro o dovrebbe essere evitato a meno che non sia assolutamente necessario.

È stato utile?

Soluzione

Quando dovrebbe essere utilizzata la serratura?

È necessario utilizzare un blocco per proteggere le risorse condivise nel codice multithread.Non per altro.

Ma è necessario quando l'applicazione non crea altri thread?

Assolutamente no.E' solo una perdita di tempo.Tuttavia assicurati di non utilizzare implicitamente i thread di sistema.Ad esempio, se utilizzi I/O asincrono potresti ricevere callback da un thread casuale, non dal thread originale.

Ci sono problemi di prestazioni con l'utilizzo del blocco?

SÌ.Non sono molto grandi in un'applicazione a thread singolo, ma perché effettuare chiamate che non ti servono?

...se questo è un buon modello di progettazione da seguire in futuro[?]

Bloccare tutto, volenti o nolenti, è un modello di progettazione terribile.Se il tuo codice è ingombro di blocchi casuali e poi decidi di utilizzare un thread in background per qualche lavoro, è probabile che ti imbatti in deadlock.La condivisione di una risorsa tra più thread richiede un'attenta progettazione e più riesci a isolare la parte difficile, meglio è.

Altri suggerimenti

Tutte le risposte qui sembrano giuste:L'utilità dei lock è quella di impedire ai thread di accedere contemporaneamente al codice bloccato.Tuttavia, ci sono molte sottigliezze in questo campo, una delle quali è che i blocchi di codice bloccati vengono automaticamente contrassegnati come regioni critiche da Common Language Runtime.

L'effetto del codice contrassegnato come critico è che, se l'intera regione non può essere eseguita interamente, il runtime potrebbe considerare che l'intero dominio dell'applicazione è potenzialmente compromesso e, pertanto, scaricarlo dalla memoria.Per citare MSDN:

Si consideri, ad esempio, un'attività che tenta di allocare memoria mantenendo un blocco.Se l'allocazione della memoria non riesce, interrompere l'attività corrente non è sufficiente per garantire la stabilità dell'AppDomain, poiché potrebbero esserci altre attività nel dominio in attesa dello stesso blocco.Se l'attività corrente viene terminata, altre attività potrebbero essere bloccate.

Pertanto, anche se la tua applicazione è a thread singolo, questo potrebbe rappresentare un pericolo per te.Considera che un metodo in un blocco bloccato genera un'eccezione che alla fine non viene gestita all'interno del blocco.Anche se l'eccezione viene gestita mentre emerge dallo stack di chiamate, la regione critica del codice non è terminata normalmente.E chissà come reagirà il CLR?

Per maggiori informazioni, leggi questo articolo sui pericoli di Thread.Abort().

Tieni presente che potrebbero esserci motivi per cui la tua applicazione non è a thread singolo come pensi.L'I/O asincrono in .NET potrebbe, ad esempio, richiamare un thread del pool, così come alcune delle varie classi timer (non il timer Windows Forms, però).

In generale, se la tua applicazione è a thread singolo, non otterrai molto utilizzo dall'istruzione lock.Non conoscendo esattamente la tua applicazione, non so se siano utili o meno, ma sospetto di no.Inoltre, se la tua applicazione utilizza lock ovunque, non so se mi sentirei comunque così sicuro che funzioni in un ambiente multi-thread - ha fatto lo sviluppatore originale In realtà sanno come sviluppare codice multi-thread o hanno semplicemente aggiunto istruzioni di blocco ovunque nella vaga speranza che questo avrebbe funzionato?

lock dovrebbe essere utilizzato attorno al codice che modifica lo stato condiviso, lo stato che viene modificato da altri thread contemporaneamente e gli altri gradini devono adottare lo stesso blocco.

Un blocco è in realtà un serializzatore di accesso alla memoria, i thread (che accettano il blocco) attenderanno che il blocco entri finché il thread corrente non esce dal blocco, quindi l'accesso alla memoria viene serializzato.

Per rispondere alla tua domanda, il blocco non è necessario in un'applicazione a thread singolo e ha effetti collaterali sulle prestazioni.perché i blocchi in C# sono basati su oggetti di sincronizzazione del kernel e ogni blocco eseguito crea una transizione alla modalità kernel dalla modalità utente.

Se sei interessato alle prestazioni multithreading, un buon punto di partenza è Linee guida per il threading MSDN

Voi Potere hai problemi di prestazioni con le variabili di blocco, ma normalmente costruiresti il ​​tuo codice per ridurre al minimo il tempo trascorso all'interno di un blocco di codice "bloccato".

Per quanto riguarda la rimozione delle serrature.Dipenderà da cosa sta facendo esattamente il codice.Anche se è a thread singolo, se il tuo oggetto è implementato come Singleton, è possibile che più client ne utilizzino un'istanza (in memoria, su un server) contemporaneamente.

Sì, ci sarà una certa riduzione delle prestazioni quando si utilizza il blocco, ma generalmente è abbastanza trascurabile da non avere importanza.

L'uso dei lock (o qualsiasi altra istruzione o costrutto di mutua esclusione) è generalmente necessario solo in scenari multi-thread in cui più thread (creati dall'utente o dal chiamante) hanno l'opportunità di interagire con l'oggetto e modificare lo stato sottostante o dati mantenuti.Ad esempio, se hai una raccolta a cui possono accedere più thread, non vuoi che un thread modifichi il contenuto di quella raccolta rimuovendo un elemento mentre un altro thread sta tentando di leggerlo.

Lock(token) viene utilizzato solo per contrassegnare uno o più blocchi di codice che non devono essere eseguiti contemporaneamente in più thread.Se la tua applicazione è a thread singolo, protegge da una condizione che non può esistere.

E il blocco invoca un calo delle prestazioni, aggiungendo istruzioni per verificare l'accesso simultaneo prima che il codice venga eseguito.Dovrebbe essere utilizzato solo dove necessario.

Vedi il domanda su "Mutex" in C#.E poi guarda questi due domande riguardanti l'uso specifico dell'istruzione 'lock(Object)'.

Non ha senso avere blocchi nell'app se c'è un solo thread e sì, è un calo di prestazioni, anche se è necessario un discreto numero di chiamate affinché quel successo si trasformi in qualcosa di significativo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top