2

I have been told that multicast delegate in C# is immutable.But this code below seems to prove it is not.

Action a = () => { };
Action b = a;
Console.WriteLine(ReferenceEquals(a, b));

It will display True instead of False. Here is another example:

public delegate void MyHandler();
public class Klass
{
    public event MyHandler onCreate;

    public void Create()
    {
        MyHandler handler = onCreate;
        if (handler != null)
        {
            handler();
        }

        Console.WriteLine(ReferenceEquals(handler, onCreate));
    }
}

This class will be invoked as below:

Klass k = new Klass();
k.onCreate += () => { };

k.Create();

Same as above it will display True,so how could it be thread safe if the local copy is the same reference as the orignal one?

KevinY
  • 23
  • 3
  • 3
    *But this code below seems to prove it is not.* No, it doesn't. You're doing a reference assigment, nothing more. Immutability isn't about referencing an object multiple times, it's about having a new copy once it's state changes. – Yuval Itzchakov Apr 09 '15 at 04:34
  • You may want to have a look at http://stackoverflow.com/questions/5057267/what-is-the-difference-between-a-reference-type-and-value-type-in-c – Alex Apr 09 '15 at 04:44

2 Answers2

2

How could it be thread safe if the local copy is the same reference as the orignal one?

I think you may have misunderstood the meaning of immutability. This is how wikipedia defines it:

In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created. This is in contrast to a mutable object, which can be modified after it is created.

A reference assigment from variable a to b does not change the state of the delegate. Hence, multiple threads invoking the same delegate are guaranteed to be invoking the same constructed delegate. Note, this does not mean the underlying method referenced by that delegate is thread safe. Remember, delegates in C# are reference types and they are copied by value, which in their case is the address to the object held by in the GC heap, not the copy of the value itself. More on delegate thread safety in Are C# delegates thread-safe?

Community
  • 1
  • 1
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
2

There are two concepts that make this pattern thread-safe.

  • The delegate is immutable. Once it is created it will never change. That means you can use it in code and not have to worry about another thread changing it.
  • Reference assignments are atomic. Copying the reference to a local variable prevents a race condition between one thread clearing out the multicast chain and the current thread assuming it will reference something other than null.

One possible confusion here is that an event works similar to a variables in that it holds a reference to the multicast delegate. When you do += or -= on it will construct a new multicast delegate and assign the newly created object to the event "variable". The delegate is still immutable so it will never change. It is the event that is not and can be changed by another thread.

Brian Gideon
  • 47,849
  • 13
  • 107
  • 150