views:

76

answers:

2

Not sure what I'm doing wrong:

class MyClass
{

    private EventInfo eventInfo;

    public void OnGenerateEvent(object sender, EventArgs e)
    { 
        // Called from *main* thread 

        // Load assembly and set eventInfo here
        eventInfo = ....GetEvent(...);
        eventInfo.AddEventHandler(source, handler);

        // Call to a static method in another assembly
        someMethodInfo.Invoke(null, null);

    }


    public void OnEventChanged(object sender, EventArgs args)
    {    
        // Called from a *worker* thread created 
        // by that static method in the other assembly

        eventInfo is null here !   

        // Trying to remove handler
        eventInfo.RemoveEventHandler(.....);

    }


    // But...
    protected override void Dispose(bool disposing)
    {
        // Called from *main* thread when program closes

        eventInfo is *not* null here
    }
}
+2  A: 

You'll need to do at least one of the following:

  • make eventInfo volatile to ensure that OnGenerateEvent() writes it all the way out to memory before calling someMethodInfo.Invoke()

  • use something like a mutex/lock to protect access to eventInfo. This will also provide the proper memory barriers (this is what really should be done in my opinion)

Oh, and I'm assuming that there aren't really 2 different MyClass instances involved - that can't be verified by the code you've shown.

Michael Burr
+5  A: 

I think we'd need to see reproducible code, but I can see 4 scenarios:

  • you are talking to a different MyClass instance in the two cases - my bet is here
  • you have a variable called eventInfo in one of the methods (try using this.eventInfo when you mean the field if there is any ambiguity)
  • the write or read is cached (try marking the field volatile; again unlikely)
  • a thread-specific field (thread-local storage) - very unlikely

The first two are much more likely.

Marc Gravell