Per rispondere alla tua domanda (come alcuni altri hanno già fatto), ci sono alcuni potenziali problemi con l'esempio di codice che hai fornito:
private static string mutex= "ABC";
- La variabile
mutex
non è immutabile.
- La stringa letterale
"ABC"
farà riferimento allo stesso riferimento all'oggetto internamente in qualsiasi punto dell'applicazione.
In generale, vorrei sconsigliare il blocco delle stringhe. Tuttavia, c'è un caso in cui mi sono imbattuto dove è utile farlo.
Ci sono state occasioni in cui ho mantenuto un dizionario di oggetti di blocco in cui la chiave è qualcosa di unico su alcuni dati che ho. Ecco un esempio inventato:
void Main()
{
var a = new SomeEntity{ Id = 1 };
var b = new SomeEntity{ Id = 2 };
Task.Run(() => DoSomething(a));
Task.Run(() => DoSomething(a));
Task.Run(() => DoSomething(b));
Task.Run(() => DoSomething(b));
}
ConcurrentDictionary<int, object> _locks = new ConcurrentDictionary<int, object>();
void DoSomething(SomeEntity entity)
{
var mutex = _locks.GetOrAdd(entity.Id, id => new object());
lock(mutex)
{
Console.WriteLine("Inside {0}", entity.Id);
// do some work
}
}
L'obiettivo di codice come questo è quello di serializzare invocazioni concorrenti del DoSomething()
nel contesto dell'entità del Id
. Il rovescio della medaglia è il dizionario. Più sono le entità, più diventa grande. È anche solo più codice da leggere e pensare.
Penso.internato stringa di NET può semplificare le cose:
void Main()
{
var a = new SomeEntity{ Id = 1 };
var b = new SomeEntity{ Id = 2 };
Task.Run(() => DoSomething(a));
Task.Run(() => DoSomething(a));
Task.Run(() => DoSomething(b));
Task.Run(() => DoSomething(b));
}
void DoSomething(SomeEntity entity)
{
lock(string.Intern("dee9e550-50b5-41ae-af70-f03797ff2a5d:" + entity.Id))
{
Console.WriteLine("Inside {0}", entity.Id);
// do some work
}
}
La differenza qui è che sto facendo leva sulla stringa di internato a darmi lo stesso riferimento a un oggetto per l'ID entità. Questo semplifica il mio codice perché non devo mantenere il dizionario delle istanze mutex.
Notare la stringa UUID codificata che sto utilizzando come spazio dei nomi. Questo è importante se scelgo di adottare lo stesso approccio di blocco su stringhe in un'altra area della mia applicazione.
Il blocco delle stringhe può essere una buona idea o una cattiva idea a seconda delle circostanze e dell'attenzione che lo sviluppatore fornisce ai dettagli.
Grazie GvS. Ma mi chiedevo se c'è una differenza nell'usare un tipo di oggetto (che generalmente facciamo) per bloccare l'uso di un tipo di stringa (la stringa essendo mutevole). il programma sta avendo un gran numero di discussioni sul thread (non è ancora sicuro se questo è dovuto a questo pezzo di codice). – Illuminati
Le stringhe non sono mutabili, sembrano semplicemente mutabili, ma ogni stringa diversa punta a un altro riferimento. Mi sembra strano bloccarli. Hai provato un ReaderWriterLock. – GvS
scusa volevo dire "string essere immutabile" :) ..non ho provato con ReaderWriterLock .. stavo solo cercando di capire la sezione esatta del codice che causa i problemi. è difficile ricreare la situcazione nell'ambiente locale a causa di dati insufficienti. ma ho intenzione di provare a riprodurlo. grazie ancora. – Illuminati