Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread-safety of event raising with null propagation [duplicate]

Are these 2 samples the same? Can old-style raising be replaced with Invoke and null propagation?

OLD:

    public event EventHandler<MyEventArgs> MyEvent;
    protected virtual void OnMyEvent(MyEventArgs args)
    {
        EventHandler<MyEventArgs> handler = this.MyEvent;
        if (handler != null)
            handler(this, args);
    }

NEW:

    public event EventHandler<MyEventArgs> MyEvent;
    protected virtual void OnMyEvent(MyEventArgs args)
    {
        this.MyEvent?.Invoke(this, args);
    }

Null check is important but it is clear. What is about additional variable?
How does null-propogation work internally? Is it thread-safe with events?

P.S. Regarding thread safety in events you can read here:
C# Events and Thread Safety

like image 710
Maxim Avatar asked Feb 12 '17 21:02

Maxim


People also ask

Are event handlers thread safe?

Bug: EventHandler is not thread safe.

Can events be null?

With this approach, the event always has at least one subscriber, and is, therefore, never null.

How to use null conditional operator in c#?

A null-conditional operator applies a member access, ?. , or element access, ?[] , operation to its operand only if that operand evaluates to non-null; otherwise, it returns null . That is, If a evaluates to null , the result of a?. x or a?[x] is null .

IS NULL operator C#?

Null-coalescing Operator(??) Null-coalescing Operator is a binary operator that simplifies checking for null values. it is used to define a default value for nullable value types or reference types. It returns the left-hand operand if the operand is not null; otherwise, it returns the right operand.


1 Answers

Given this code:

    static void Main(string[] args)
    {
        var a = new Random(1).Next() > 0 ? new object() : null;
        var b = a?.GetHashCode();
        Console.WriteLine(b);
    }

This is what I see in IL representation at line where monadic operator is called in Release mode (VS 2015):

IL_0016: dup          
IL_0017: brtrue.s     IL_0025

... //nothing iteresting, just setting null to 'a' and skip IL_0025 area

IL_0025: callvirt     instance int32 [mscorlib]System.Object::GetHashCode()

Let me explain:

  • dup - is command which copies current value on stack into new one placed in this stack (in this case it is simply duplicating value of 'a')
  • brtrue.s - transfers control to address if value on stack is true/notnull/non-zero (as of now value is copy of 'a' - it is thread-safe to use it)

So, answer to your question is: YES, it is thread-safe to use monadic operator, because it is operating over a copy.

like image 119
eocron Avatar answered Oct 17 '22 04:10

eocron