C #: Cosa succede se un metodo statico viene chiamato da più thread?

Nella mia applicazione ho un metodo statico che viene chiamato da più thread contemporaneamente. C’è qualche pericolo che i miei dati vengano confusi?

Nel mio primo tentativo il metodo non era statico e stavo creando più istanze della class. In quel caso i miei dati si sono mescolati in qualche modo. Non sono sicuro di come ciò avvenga perché succede solo a volte. Sto ancora facendo il debug. Ma ora il metodo è statico, non ho avuto problemi finora. Forse è solo fortuna. Non lo so per certo.

Le variabili dichiarate all’interno dei metodi (con la ansible eccezione delle variabili ” catturate “) sono isolate, quindi non si avranno problemi inerenti; tuttavia, se il tuo metodo statico accede a uno stato condiviso, tutte le scommesse sono distriggerste.

Esempi di stati condivisi sarebbero:

  • campi statici
  • oggetti accessibili da una cache comune (non serializzata)
  • dati ottenuti tramite i parametri di input (e lo stato su tali oggetti), se è ansible che più thread tocchino gli stessi oggetti

Se hai uno stato condiviso, devi:

  • fai attenzione a non mutare lo stato una volta che può essere condiviso (meglio: usa oggetti immutabili per rappresentare lo stato, e scatta uno stato dello stato in una variabile locale – cioè piuttosto che fare riferimento a whatever.SomeData ripetutamente, leggi whatever.SomeData una volta in una variabile locale, e quindi basta usare la variabile – nota che questo aiuta solo per lo stato immutabile!)
  • sincronizzare l’accesso ai dati (tutti i thread devono essere sincronizzati) – o lettore / scrittore (o più granulare) che si escludono a vicenda

Sì, è solo fortuna. 😉

Non importa se il metodo è statico o meno, ciò che conta è se i dati sono statici o meno.

Se ogni thread ha la propria istanza separata della class con il proprio set di dati, non vi è alcun rischio che i dati vengano confusi. Se i dati sono statici, esiste un solo set di dati e tutti i thread condividono gli stessi dati, quindi non c’è modo di non mischiarli.

Quando i tuoi dati in istanze separate vengono ancora mescolati, è molto probabile perché i dati non sono realmente separati.

I metodi statici dovrebbero andare bene per più thread.

I dati statici invece potrebbero causare un problema perché i tentativi di accedere agli stessi dati da thread diversi devono essere controllati per garantire che solo un thread alla volta stia leggendo o scrivendo i dati.

MSDN dice sempre:

Qualsiasi membro statico pubblico (Shared in Visual Basic) di questo tipo è thread-safe. Non è garantito che tutti i membri di istanza siano thread-safe.

Modifica: come dicono i ragazzi qui, non è sempre il caso, e chiaramente questo vale per le classi progettate in questo modo nel BCL, non per le classi create dall’utente dove questo non si applica.