CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Sep 2004
    Posts
    561

    Something about C# events that I don't understand.

    Why does this occur?
    I have a piece of code that looks like the the following:

    Code:
      
    void MyEvent()
    {
    if( m_bDoSomething )
    {
    	DoSomething();
    	
    	m_bDoSomething = false;
    }
    }
    By default "m_bDoSomething" is set to true.
    MyEvent() is a function that a C# delegate gets mapped to.

    The bug is that "DoSomething" gets called twice in a row.

    MyEvent() appears to be triggered twice in my application but as I step through the debugger it "appears" that this function is called from two separate threads.
    For instance, I set break points at DoSomething() and m_bDoSomething.

    Here is the sequence of break points that I see in the debugger.

    1. DoSomething();
    2. DoSomething();
    3. m_bDoSomething = false;
    4. m_bDoSomething = false;

    You would think... no problem... just synchronize this function...
    HOWEVER, the debugger reports only one thread throughout the sequence above and also in our log files when we report the thread ID along with a trace statement in MyEvent()

    Can anybody shed light on what may be happening here?
    Thank you.

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Something about C# events that I don't understand.

    Does the DoSomething() method set m_bDoSomething = true?

  3. #3
    Join Date
    Mar 2004
    Location
    Prague, Czech Republic, EU
    Posts
    1,701

    Re: Something about C# events that I don't understand.

    The two calls are dependant (trought m_bDoSomething), but due to they are fired from different threads, you cannot rely on the execution order. I think you have two options: 1.) use lock to synchronize the threads (I think it is not the best way it events are in the play), or 2.) consider redesign the application.

    And maybe the 3rd solution, try to rewrite the code:
    Code:
    void MyEvent()
     {
       m_bDoSomething = false;
       if( m_bDoSomething )
       {
    	DoSomething();
       }
     }
    If I understood well, this is what you want. But I'm not sure if is 100% reliable due to nature of .NET's memory model.
    • Make it run.
    • Make it right.
    • Make it fast.

    Don't hesitate to rate my post.

  4. #4
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    Re: Something about C# events that I don't understand.

    Sounds like the method DoSomething is calling MyEvent to be called - even though it's being called from inside the event.

    Besides the fact that an event handler should never call a method which is capable of raising it again, maybe you mean to do something like this :

    Code:
    private bool m_inMyEvent = false;
    
    void MyEvent()
    {
        if (!m_inMyEvent)
        {
            m_inMyEvent = true;
            DoSomething();
            m_inMyEvent = false;
        }
    }
    I.e. don't re-enter the event once you're in it.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  5. #5
    Join Date
    Sep 2004
    Posts
    561

    Re: Something about C# events that I don't understand.

    Thank you everyone.

    Arjay: I'm 100% positive that DoSomething does not set m_bDoSomething = true.

    boudino: locking does not work since both events are fired on the same thread. But I have no idea why they appear to be context switching and why it appears to be two different threads? But VS2005 only reports one thread and even my log traces with the thread ID printed out are the same.

    darwen: I'm 100% positive that DoSomething does not call MyEvent.


    The "hack" fix is:

    Code:
     
    void MyEvent()
    {
    if( m_bDoSomething )
    {
     m_bDoSomething = false;
     DoSomething();
    }
    }
    I don't want to go that route...
    I'm very disturbed that this is occurring.

    Here is essentially what the stack trace boils down to during each call:

    1. DialogForm.OnClosed
    2. OnDoMyEvent
    3. MyEvent

    It's interesting that DialogForm.OnClosed gets called twice.
    Not quite sure why that's happening, I'll have to do more digging.

  6. #6
    Join Date
    Sep 2004
    Posts
    561

    Re: Something about C# events that I don't understand.

    Quote Originally Posted by darwen
    Sounds like the method DoSomething is calling MyEvent to be called - even though it's being called from inside the event.

    Besides the fact that an event handler should never call a method which is capable of raising it again, maybe you mean to do something like this :

    Code:
    private bool m_inMyEvent = false;
     
    void MyEvent()
    {
    if (!m_inMyEvent)
    {
    m_inMyEvent = true;
    DoSomething();
    m_inMyEvent = false;
    }
    }
    I.e. don't re-enter the event once you're in it.
    Ahh... I looked at the code a third time...
    I think you are right.

    Very good catch!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured