Safely Initialising a static variable to a file This might appear to be a trivial task, but I think it's not the case. My code originally looked like this:

class DataSetToPdf
{
  static byte [] F1 = Util.GetFile( "C:\PdfFiles\FreeSans.ttf" );
  public static void Go( Data.DataSet ds, int ix, System.IO.Stream output )
  {
    // Code which uses F1
  }
}


Util.GetFile simply reads the file and returns an array of bytes. For completeness, here it is:

class Util
{
  public static byte[] GetFile( String path )
  {
    IO.MemoryStream ms = new IO.MemoryStream();
    using( IO.FileStream f = IO.File.OpenRead( path) )
    {
      f.CopyTo( ms );
    }
    return ms.ToArray();
  }
}


However, when using DataSetToPdf in a multi-threaded environment (IIS), I was sometimes ( but not always ) getting mysterious null reference exceptions, which I could not easily debug. However, what I believe what was happening is that the static method could be called before the initialisation is complete. Instead what appears to be is necessary is this:

class DataSetToPdf
{

  static System.Object Locker = new System.Object();

  static byte [] F1;

  public static void Go( Data.DataSet ds, int ix, System.IO.Stream output )
  {
    lock( Locker )
    {
      if ( F1 == null )
      {
         F1 = Util.GetFile( "C:\PdfFiles\FreeSans.ttf" );
      }
    }
    // Code which uses F1
  }
}


Please review my updated code, was it wrong before, is it right now?
I would avoid doing this kind of thing in a static constructor or static initializer. Error handling in this situation can get tricky: errors thrown will result in a TypeInitializationException and the static constructor will not get executed again even if this is handled. You also don't have much control about where this will get thrown in your code: it would be very easy to refactor your code and end up with the first reference to the type appearing in a completely different place.

Loading from a file is also going to cause issues when you write tests: a reference to the type will trigger the static initialization and therefore depend on the presence of the file, which you will need to ensure is present in all the relevant test assemblies (and this kind of thing becomes a headache if you are using things like ReSharper's shadow copying behavior).

I would consider avoiding the use of static methods: define an interface and pass the relevant data in through the class constructor, e.g.

public interface IDataSetToPdf
{
    void Process();
} 

public class DataSetToPdf : IDataSetToPdf
{
    private readonly byte[] fontData;

    public DataSetToPdf(byte[] fontData)
    {
        this.fontData = fontData ?? throw new ArgumentNullException(nameof(fontData));
    }

    public void Process()
    {
        // do stuff with fontData
    }
}


There are several advantages of doing this: firstly, if the data is in a static field, it it will last as long as the application does, whereas using an instance field allows the memory to be reclaimed by the garbage collector when no further references to it remains.

Another advantage is that it makes it easier to unit test: provided you write your code against the interface IDataSetToPdf rather than the concrete class DataSetToPdf, you would be able to provide a mock implementation of the interface for your tests, which would allow you to focus your tests on the calling code rather than the combination of the calling code with DataSetToPdf.