Ho utilizzato questo modello per inizializzare i dati statici nelle mie classi. Mi sembra thread-safe, ma so quanto possano essere sottili problemi di threading. Ecco il codice:Inizializzazione di variabili statiche thread-safe
public class MyClass // bad code, do not use
{
static string _myResource = "";
static volatile bool _init = false;
public MyClass()
{
if (_init == true) return;
lock (_myResource)
{
if (_init == true) return;
Thread.Sleep(3000); // some operation that takes a long time
_myResource = "Hello World";
_init = true;
}
}
public string MyResource { get { return _myResource; } }
}
Ci sono dei buchi qui? Forse c'è un modo più semplice per farlo.
AGGIORNAMENTO: Il consenso sembra essere che un costruttore statico è la strada da percorrere. Ho trovato la seguente versione usando un costruttore statico.
public class MyClass
{
static MyClass() // a static constructor
{
Thread.Sleep(3000); // some operation that takes a long time
_myResource = "Hello World";
}
static string _myResource = null;
public MyClass() { LocalString = "Act locally"; } // an instance constructor
// use but don't modify
public bool MyResourceReady { get { return _myResource != null; } }
public string LocalString { get; set; }
}
Spero che questo è meglio.
@RaoulRobin, un costruttore statico sarebbe in ordine, ma solo se si desidera una classe statica. Se non si desidera condividere i campi in tutte le istanze di MyClass, è necessario utilizzare la sincronizzazione corretta. – Kiril
Nella versione reale la risorsa statica è Dictionary <> che viene precaricata, anziché essere letta contemporaneamente in più istanze della classe. MSDN dice che le letture concorrenti sono OK finché il dizionario non viene modificato durante le letture. Grazie per il commento. – RaoulRubin