Are C# auto-implemented static properties thread-safe?

10,861

Solution 1

It appears not. This is the decompilation with Reflector:

private static string Test
{
    [CompilerGenerated]
    get
    {
        return <Test>k__BackingField;
    }
    [CompilerGenerated]
    set
    {
        <Test>k__BackingField = value;
    }
}

Solution 2

Section 10.7.4 of the C# specification states:

When a property is specified as an automatically implemented property, a hidden backing field is automatically available for the property, and the accessors are implemented to read from and write to that backing field. The following example:

public class Point {
  public int X { get; set; } // automatically implemented
  public int Y { get; set; } // automatically implemented
}

is equivalent to the following declaration:

public class Point {
  private int x;
  private int y;
  public int X { get { return x; } set { x = value; } }
  public int Y { get { return y; } set { y = value; } }
}

That's what we promise, and that's what you get. The point of auto properties is to do the most basic, simple, cheap thing; if you want to do something fancier then you should write a "real" property.

Solution 3

No. You must wrap them in thread-locking mechanisms.

object _lock = new object();
public static Main(string[] args)
{
    lock(_lock)
    {
         Prop = new T();
    }


    T val = null;
    lock(_lock)
    {
         val = Prop;
    }
}

Solution 4

For completeness, field-like events do have thread-safety built in, but they are alone in this. Automatically implemented properties do not have any such features. You can, however, do something like:

public static double SomeProp
{   // ### NOT RECOMMENDED ###
    [MethodImpl(MethodImplOptions.Synchronized)] get;
    [MethodImpl(MethodImplOptions.Synchronized)] set;
}

The problem with this is that it will lock the Type, which is a bad thing. I would implement my own synchronization for this, personally.

Solution 5

There is no synchronization provided with automatic properties, including static properties.

If you need full thread safety, you'll want to use your own properties with a backing field, and handle the synchronization yourself.

Share:
10,861

Related videos on Youtube

Miguel Angelo
Author by

Miguel Angelo

I'm a former web-dev and now wannabe scientist focusing in machine learning. I currently study at UFRJ, one of the best universities in Brazil ;), and also work there in a research project involving information security and machine learning. My passions are: Machine intelligence Optimization Formal languages Low level understanding Exploration I started my path with Visual Basic 5, at the age of 13, more than 20 years ago. Soon I found it insufficient, but I liked it, so started C++ and did a lot of interop with them, and sometimes assembly. Then I worked with a friend using PHP4 for 1 year. After my 1st try into university, I worked with C# for 4 years, and continued using it up to this date, though less frequently every year. At the moment, I am back to university, since 2016, and work with Python and machine learning doing research in the field of information security.

Updated on January 29, 2020

Comments

  • Miguel Angelo
    Miguel Angelo over 4 years

    I would like to know if C# automatically implemented properties, like public static T Prop { get; set; }, are thread-safe or not. Thanks!

    • Pavel Minaev
      Pavel Minaev over 14 years
      You'd have to define what exactly you mean by "thread safe" in this particular instance, first.
    • Miguel Angelo
      Miguel Angelo over 14 years
      By thread-safe I mean, if I write the value in one thread, and another thread tries to read it, could the second thread get a wrong value.
  • Robert Fraser
    Robert Fraser over 14 years
    That's kind of wrong. .NET's memory model guarantees that writes to them will be atomic and seen by all threads, at least for the regular .NET Framework, and if they are not virtual they will always be inlined. Both are implementation details of the .NET desktop framework and are not guaranteed by the spec, though.
  • Robert Fraser
    Robert Fraser over 14 years
    er I mean the decompilation is correct, but the way they are implemented guarantees atomicity, at least for integers and reference types (with the obvious caveat that atomicity != thread safety). For longs/doubles/structs/etc., you're on you're on your own, though.
  • Marc Gravell
    Marc Gravell over 14 years
    The spec guarantees that things like Int32, float and references are atomic. It doesn't make many guarantees about thread visibility / register caching etc.
  • Miguel Angelo
    Miguel Angelo over 14 years
    is that k__BackingField that you decompiled volatile?
  • Robert Fraser
    Robert Fraser over 14 years
    Err... isn't that kind of the definition of atomic?: en.wikipedia.org/wiki/Atomicity_%28programming%29 ... At least on x86/x64, a fence after write should be sufficient to guarantee that "if one thread sees it, all threads see it".
  • Marc Gravell
    Marc Gravell over 14 years
    As I understand it in this context, "atomic" means that it can't be seen mid-update. For example, double is not guaranteed atomic; if you change a double field from {x} to {y}, another thread could see it after only the first half has been updated - it could get a different number ({z}) that has never existed as a "real" value of the field (huge corruption issue).
  • Miguel Angelo
    Miguel Angelo over 14 years
    I think atomic is defined as "in one, unsplitable step"... such that nothing happens concurrently with that instruction... but it does not mean that, it will sync processor caches... if that was automatic, multiprocessing would have no meaning at all
  • Miguel Angelo
    Miguel Angelo over 14 years
    I'm wrong, it is not that it does not have concurrency, but that it can not be broken, once it has started.
  • x0n
    x0n over 14 years
    "bad" for reasons of "marshal-by-bleed" where the Type lock bleeds into other isolated appdomains in the same process...
  • Marc Gravell
    Marc Gravell over 14 years
    It is bad enough just with one app-domain truth be told.
  • quentin-starin
    quentin-starin over 14 years
    @Miguel: No, it is not volatile. I apologize for not responding sooner, busy day and all ...
  • Admin
    Admin over 14 years
    Prop and T are from the question.
  • Robert Fraser
    Robert Fraser over 14 years
    volatile = the compiler will not reorder it.
  • NathanAldenSr
    NathanAldenSr over 4 years
    Well, it is Eric Lippert answering... :-D