Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8151071
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 6, 20262026-06-06T15:15:28+00:00 2026-06-06T15:15:28+00:00

A common practice to avoid race conditions (in multi-threaded apps) when triggering events is

  • 0

A common practice to avoid race conditions (in multi-threaded apps) when triggering events is this:

EventHandler<EventArgs> temp = SomeEvent;
if (temp != null) temp(e);

"Remember that delegates are immutable and this is why this technique works in theory. However, what a lot of developers don't realize is that this code could be optimized by the compiler to remove the local temp variable entirely. If this happens, this version of the code is identical to the first version, so a NullReferenceException is still possible."

The problem (according to the book) is that “this code could be optimized by the compiler to remove the local temp variable entirely. If this happens, this version of the code is identical to the first version, so a NullReferenceException is still possible”

According to CLR via C#, here is a better way to force the compiler to copy the event pointer.

virtual void OnNewMail(NewMailEventArgs e)
{
    EventHandler<NewMailEventArgs> temp =
                          Interlocked.CompareExchange(ref NewMail, null, null);
    if (temp != null) 
        temp(this, e);
}

Here, CompareExchange changes the NewMail reference to null if it is null and does not alter NewMail if it is not null. In other words, CompareExchange doesn’t change the value in NewMail at all, but it does return the value inside NewMail in an atomic, thread-safe way.
Richter, Jeffrey (2010-02-12). CLR via C# (p. 265). OReilly Media – A. Kindle Edition.

I am on .Net 4.0 framework, and not sure how this can possibly work, because Interlocked.CompareExchange expects a reference to a location, not a reference to a event.

Either there is an error in the book, or I misinterpreted it. Has anyone implemented this method? Or have a better way to prevent race conditions here?

UPDATE

it was my mistake, the iterlocked code works. i just had wrong casting specified, but according to Bradley (below) it is not necessary in .net 2.0 and up on windows.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-06T15:15:31+00:00Added an answer on June 6, 2026 at 3:15 pm

    The compiler (or JIT) is not allowed to optimize that if/temp away (in CLR 2.0 and later); the CLR 2.0 Memory Model does not allow reads from the heap to be introduced (rule #2).

    Thus, MyEvent can not be read a second time; the value of temp must be read in the if statement.

    See my blog post for an extended discussion of this situation, and an explanation of why the standard pattern is fine.

    However, if you are running on a non-Microsoft CLR (e.g., mono) that doesn’t provide the CLR 2.0 memory model guarantees (but only follows the ECMA memory model), or you’re running on Itanium (which has a notoriously weak hardware memory model), you will need code like Richter’s to eliminate a potential race condition.

    In regards to your question about Interlocked.CompareExchange, the syntax public event EventHandler<NewMailEventArgs> NewMail is just C# syntactic sugar for declaring a private field of type EventHandler<NewMailEventArgs> and a public event that has add and remove methods. The Interlocked.CompareExchange call reads the value of the private EventHandler<NewMailEventArgs> field, so this code does compile and work as Richter describes; it’s just unnecessary in the Microsoft CLR.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I was wondering, whether the following style is a common practice to avoid key
I thought this would be a very common practice, but I am having a
It's common practice for tables of regression outcomes in academic papers to have a
It's at least common practice to treat null BSTR (null WCHAR* pointer) as an
Here's a common practice I see often (including from a very popular iPhone developer
What's the common practice to deal with Integer overflows like 999999*999999 (result > Integer.MAX_VALUE)
What is common practice given the two xml formats? And how would you go
In Java IoC / DI is a very common practice which is extensively used
Using get/set seems to be a common practice in Java (for various reasons), but
I am aware that most common practice would be to put var a,b; on

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.