none
How to prevent the main thread from entering a deadlock RRS feed

  • Question

  • Hi,

    i have a program that runs multiple threads, two of them are running unmanaged C++ DLL, while the program is working, it suddenly hangs for no reason (while the threads running on the DLL are working normally), when i try to see what makes the UI hangs, i find the following in the stack :


      [Managed to Native Transition] 
      System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason = 2, int pvLoopData = 0) + 0x2f1 bytes 
      System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = 2, System.Windows.Forms.ApplicationContext context = null) + 0x17d bytes 
      System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x53 bytes 
      System.Windows.Forms.dll!System.Windows.Forms.Application.DoEvents() + 0x15 bytes 


    the hanging happens in 2 situations,
    1 - in the main thread, at the  Application.Run(new MainForm());
    2 - sometimes when calling Application.DoEvents();

    iam using this method for the thread-safty issue : 

    private void SetText(string text)

    {

    if (this.ConnectionTimerLabel.InvokeRequired)

    {

    SetTextCallback d = new SetTextCallback(ConnectionTimerLabel_SetText);

    this.Invoke(d, new object[] { text });

    }

    else

    {

    this.ConnectionTimerLabel.Text = text;

    }

    }

    does calling this method cause a deadlock?

    Thank you.

    Tuesday, March 24, 2009 12:21 AM

All replies

  • Both the call stack you posted and the "2 situations" you documented show that the UI thread is *not* deadlocked.  It is running the message loop, like it should.

    One possible explanation is that you are calling SetText() too often.  Do it at a rate of more than about 1000 times per second and the UI thread gets bogged down handling the Invoke() requests, not getting time anymore to pump the message loop.  It will stop painting windows and the keyboard and mouse no longer work.  Throttle the rate, nobody can see an update rate faster than about 25 times per second.

    Hans Passant.
    Tuesday, March 24, 2009 12:45 AM
    Moderator
  • Hi,

    thank you for your reply,

    iam logging and tracing every function in the program, the SetText is not called at all before the hanging.
    could it be using the normal methods like label1.Text = "something" and label1.paint()?
    do you suggest that i log every call to the UI? iam sure it is not even 10 times per a second.

    iam using .NET Remoting, does remoting cause hanging like this?


    another thing please, can you tell me how to see the messages? maybe i can understand the problem

    Tuesday, March 24, 2009 1:14 AM
  • You can see the messages with Spy++.
    Hans Passant.
    Tuesday, March 24, 2009 7:04 AM
    Moderator
  • I ran Spy++ and waited for this hang to happen, the last messages were :

    <03421> 001B1B5E S WM_CTLCOLORSTATIC hdcStatic:11013787 hwndStatic:00291B0A
    <03422> 001B1B5E R WM_CTLCOLORSTATIC hBrush:01900015
    <03423> 001B1B5E S WM_DRAWITEM idCtl:2693898 lpdis:03DFDAA0
    <03424> 001B1B5E R WM_DRAWITEM fProcessed:False
    <03425> 001B1B5E S WM_NOTIFY idCtrl:1317798 pnmh:03DFDA84
    <03426> 001B1B5E R WM_NOTIFY
    <03427> 001B1B5E S WM_NOTIFY idCtrl:1317798 pnmh:03DFDA84
    <03428> 001B1B5E R WM_NOTIFY
    <03429> 001B1B5E S WM_NOTIFY idCtrl:1317798 pnmh:03DFDA84
    <03430> 001B1B5E R WM_NOTIFY
    <03431> 001B1B5E S WM_NOTIFY idCtrl:1317798 pnmh:03DFDA84
    <03432> 001B1B5E R WM_NOTIFY
    <03433> 001B1B5E P WM_POWERBROADCAST (long)dwPowerEvent:PBT_APMPOWERSTATUSCHANGE dwData:00000000



    this cycle of messages was repeated many times, but for no reason it hanged on this place, i was monitoring the main window, could it be a control? what should i do next?

    another thing, i said before that iam using .NET Remoting, when this hang happens, other programs cant raise events in the hanging program anymore, can i assume that there is a .NET Remoting message that is hanging the UI thread?

    please help me!!!
    Tuesday, March 24, 2009 11:11 AM
  • Hi again,

    i tried to use the Application.AddMessageFilter to log every message before it is dispatched, and noticed that the last message appears before the program hangs is :

    msg=0x400 (WM_USER) hwnd=0x301bd6 wparam=0xbabe lparam=0x7beb564 result=0x0

    this message appeared many times, but doesnt always hang, i tried to filter it out, everything is working now.

    but what was the real problem?

    Tuesday, March 24, 2009 3:18 PM
  • You can't just filter a message, something else is going to break.  You've got the window handle, use Spy++ to find out what window is getting this message.  It would be more than likely some kind of hidden window, one that uses this message to synchronize something.  The message is posted with PostMessage(), that's a strong hint that it some kind of threading helper.  From the window class name, you might get an idea what this window does.  Don't be surprised if it is associated with Remoting.
    Hans Passant.
    Tuesday, March 24, 2009 4:04 PM
    Moderator
  • i know that i should not filter it, but a debug error happens when i filter it, after a while of running the program, the VS.NET breaks and give me this message : 


    The CLR has been unable to transition from COM context 0x1a15f8 to COM context 0x1a1768 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.

    when i ignore this error and continue, everything goes ok, i mean there is no difference in the program.


    about the hwnd of the WM_USER, it belongs to the following class : OleMainThreadWndClass
    iam using Windows Media Encoder 9, when i call the start method of the encoder, and exactly after my function returns, this message is posted.

    so any idea weither i can saftly remove the message or how to avoid making the message hang the program?
    Tuesday, March 24, 2009 6:02 PM
  • Hmya, you are killing COM's apartment threading marshaller.  I'm going to hide now, good luck with it.

    Hans Passant.
    Tuesday, March 24, 2009 6:29 PM
    Moderator
  • Make sure you have [STAThread] on your Main function.

           -Steve
    Wednesday, March 25, 2009 1:16 PM
  • Hello

    I have exactly the same problem in my application.

    handle is OleMainThreadWndClass handle, I have same 0xbabe wparam parameter and lparam change for each message.

    If I kill the first WM_USER message, application is not freeze
    If I don't kill it, I Receive WM_USER + 3 (0x403) on the same handle, and the message loop continu as long as Long I do not kill the process

    Very strange : If I do a Right Clic on the "button" of application in the TaskBar, The infinite loop stops !!!

    My context is a little bit complex to explain

       1. Process A Launch process B with a command Line action
       2. Process A do a loop FindWindow("xxx") to find a handle in Process B with xxx class name
       3. Process A send a my own USER message to Process B by the previous handle
       4. Process B receive the message and Show a modal window.

    In fact, if duration between 1 and 2 is very short, I have my Bug, If I do a sleep(500 ms.) call >> no infinite loop occurs

    Process A is a native process (Delphi 32 bits application), this EXE is the sender.
    Process B is a WPF application which hosts a Delphi native DLL, This DLL is the receiver

    the previous communication process is included in 2 own COM/ActiveX components (TIPCClient and TIPCServer)

    and the last thing : theses components work fine maybe since 5 years BUT Sender and receiver was be a Delphi EXE.

    Could you give me some advices or help me to find a solution

    Thanks a lot for your help

    Best Regards
    Friday, October 9, 2009 10:14 PM