|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Registered User
Iscritto dal: Nov 2007
Messaggi: 4
|
[C#] Multithreading e utilizzo dei Lock. Delucidazioni?
Ciao ragazzi spiego il mio problema!
Ho una applicazione console in C# che opera in multithreading e per questo sono costretto ad utilizzare dei costrutti Lock(nomeoggetto) per lockare momentaneamente porzioni di metodi per evitare che siano accessibili contemporaneamente da più thread allo stesso tempo. Per instanziare i costrutti di Lock ho operato in questo modo: - Ho creato vari oggetti dichiarandoli private static (private static object nomeoggetto = new Object() ) - Nei metodi locko un determinato oggetto (ogni lock ha un suo oggetto diverso). Mi sono però subito reso conto di un problema che accade sui Dictionary e sulle List. Avendo oggetti di Lock differenti può capitare che se metodo A sta effettuando (se pur lockato) un enumerazione su una Lista ed arriva metodo B (lockato mediante un altro oggetto) e tenta di enumerare sulla stessa Lista, io mi ritrovo con la mia bella eccezione "Collection Was modified". Quindi ho optato per un altra soluzione: I metodi che lavorano sulla stessa Lista vengono lockati con oggetti uguali in modo che solo un metodo alla volta possa ottenere il token di lock e svolgere le operazioni al suo interno. Ora la mia domanda è: quel che sto facendo ed il mio ragionamento sono esatti? O solitamente è buona abitudine lockare UN SOLO oggetto per classe ed utilizzare sempre quello in tutti i metodi?? Non so se mi sono spiegato bene. In tal caso proverò a spiegarmi meglio! Grazie mille per l'attenzione! |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Ciao, non conosco C#, ma so che assomiglia molto a Java.
Invece di usare lock espliciti come stai facendo, non sarebbe meglio usare delle collezioni thread-safe? Lo chiedo perchè appunto in Java ci sono, mi stupirei se non ci fossero anche nel framework .NET...
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Se stai usando .Net 4 potresti trovare quello che ti serve in System.Collections.Concurrent
|
|
|
|
|
|
#4 |
|
Registered User
Iscritto dal: Nov 2007
Messaggi: 4
|
il fatto è che in questo modo mi tocca riscrivere tutto il codice per sostituire tutti i Dictionary e tutte le List dato che ho provato a fare una semplice sostituzione ma vedo che alcuni attributi di Dictionary non sono più gli stessi per ConcurrentDictionary
|
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
Certo, poi dipende da quanto è complesso quello che devi fare. Per le collezioni ci sarebbe da dire che se vincoli tutti i clienti che operano (per esempio) su una lista a possedere il lock su un singolo oggetto per tutto il tempo della chiamata ad un qualsiasi metodo (come ho detto prima) riesci certamente a garantire la sincronicità degli accessi da parte di più thread, ma solo un thread alla volta può accedere alla lista. Invece, è probabile che le collezioni concorrenti messe a disposizione dal framework .NET siano molto più performanti, perche basate su meccanismi di sincronizzazione molto più granulari (almeno nel JDK Java è così).
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 19-01-2011 alle 22:19. |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Feb 2003
Città: Stockholm (SE)
Messaggi: 1343
|
Se puoi fare una chiara distinzione tra chi scrive e chi legge, allora puoi usare il Readerwriterlock. Così chi legge non locka, ma chi scrive si (è un filo più complessa di così, leggi doc)
http://msdn.microsoft.com/en-us/libr...riterlock.aspx |
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
Da il meglio se (in termini di prestazioni) sulla collezione condivisa ci sono frequenti letture, con sporadiche e veloci scritture.
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
|
#8 |
|
Registered User
Iscritto dal: Nov 2007
Messaggi: 4
|
Grazie mille a tutti per l'aiuto, mi sto orientando verso System.Collections.Concurrent che la vedo veramente ottima per quel che mi serve inquanto le operazioni di lettura sono si frequenti ma lo sono altrettanto (e da diversi thread) quelle di scrittura!
Sto iniziando quindi a riprogrammare i miei vecchi Dictionary in ConcurrentDictionary ma mi sono bloccato nel momento in cui mi serviva enumerare gli elementi dell'oggetto dictionary. Con il vecchio Dictionary avrei fatto: Dictionary<tKey, tValue>.Enumerator ecc.. ma ora con ConcurrentDictionary non riesco a trovare niente
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Qui: http://msdn.microsoft.com/it-it/libr...onarybase.aspx puoi leggere che:
Quote:
A quale scopo enumeri il dizionario? Vedi quindi se uno di quei metodi fornisce un servizio che ti permette di ottenerlo senza dover gestire esplicitamente una enumerazione sul dizionario. Di più non so aiutarti: non conosco C# e .NET
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
|
#10 | |
|
Registered User
Iscritto dal: Nov 2007
Messaggi: 4
|
Quote:
Comunque ti ringrazio provo a dare uno sguardo a quei metodi! |
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Feb 2003
Città: Stockholm (SE)
Messaggi: 1343
|
un paio di consigli:
1) "salva" il contenuto della collezione in un array con "ToArray()" 2) prova a contenere tutta la logica che deve essere thread safe in un solo posto, così se devi cambiare meccanismo, ti è più facile. Codice:
var dict = new System.Collections.Concurrent.ConcurrentDictionary<int, string>(); dict.AddOrUpdate(1, "0", (k,ov) => "Hello world"); dict.AddOrUpdate(1, "0", (k,ov) => "Hello world"); var array = dict.ToArray(); |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 11:55.




















