14327

Interface freezes in multi-threaded c# application

Question:

I have a c# .NET multi-threaded application that is freezing the interface. What is unusual about this is that the interface does not freeze unless I let the system sit idle long enough for the screen saver to start (which requires me to reenter my password to re-gain access to the system). When the interface becomes visible again (after I have successfully entered my password) the interface is locked up. As long as I don't let the screensaver start, then the interface does not lockup.

I should point out that I have two different executables that access the same dll and this problem is occurring no matter which application I use to access the DLL. This seems to imply that the problem is in the DLL as the two applications are completely different (C++/MFC) and (C#/.NET) apart from how they relate to the DLL.

Both exes perform similar steps in how they interact with the DLL. They make calls into the dll to setup the serial port communication, open a status window in the DLL, start a thread in the DLL to monitor the comm port, and then starts a thread in the main app that monitors a stack in the dll.

When data is obtained from the comm port by the thread in the DLL, it is parsed and its results are placed on the stack and then posted to the status window via a delegate. When the thread in the exe sees data in the stack, it outputs the data in the main window, also using a delegate.

I found that if I add code to the thread inside the DLL so it calls Application.DoEvents() every 30 seconds, the interface will be frozen for about 30 seconds and then resume activity like normal. I figure something is blocking the main thread and forcing DoEvents() to fire seems to break the lock, but I have no idea what might be causing this lock.

This issue occurs both on my development machine and on a test machine.

I have tried completely removing the output of data to the status window inside the DLL, but that didn't make any difference.

I have been doing multi-threaded programming for years and never seen anything like this; so any advice would be greatly appreciated.

Thanks.

Answer1:

This is a problem that's commonly induced by the SystemEvents class when you have a non-standard way to initialize your user interface. Using threads, specifically. Start your program, Debug + Break All, Debug + Windows + Threads. If you see a thread named ".NET SystemEvents" then you're pretty much guaranteed to get this hang.

Some background: the SystemEvent class supports both console mode apps and GUI apps. For the latter, it should fire its event handlers on the UI thread. The very first time one of its events is subscribed, it creates a little invisible helper window to get the system notifications. It can do this two ways, either by creating the window on the calling thread or by starting up a helper thread. It makes the decision based on the value of Thread.GetApartmentState(). If it is STA then it can create the window on the calling thread and all event callbacks can be properly marshaled to that thread.

This goes wrong if the <em>first</em> window you create is not created on the UI thread. A splash screen for example. That window may contain controls that are interested in a system event like UserPreferenceChanged so they can properly repaint themselves. It now uses the helper thread and any event will be fired from that helper thread, not the UI thread. Poison to any window that runs on the UI thread. The session switch out of a locked workstation (including the screen saver) is for some mysterious reason very likely to cause deadlock. You may also see an occasional painting mishap, the less nasty result of using windows from the wrong thread.

Short from fixing the initialization order, a workaround is to put this in your Main() method, before <em>any</em> windows are created:

Microsoft.Win32.SystemEvents.UserPreferenceChanged += delegate { };

Answer2:

The problem does appear to be related to the ActiveX control is was probably using incorrectly in a form. I switched to using the serial port library in .NET and have not been able to reproduce my problem. Thanks to everyone, especially Hans for their assistance.

Answer3:

I am having the same issue as my PC just hangs up when the screen saver kicks off or I lock my PC and monitor goes to sleep. I am 95% sure that there are deadlocks appearing in my multithreaded app. Look and identify whether there are any deadlocks in your code.

Recommend

  • Selecting a dropdown list when inserting data from web (VBA)
  • Methods to reduce apparent lag to client from large javascript operations
  • Excel VBA Array Loop Troubleshooting: Using Redim and UBound, 1- and 2-dimensional arrays
  • Calling super.approveSelection() within a SwingWorker
  • How to download a file from internet explorer using VBA
  • Assigning {pointer to function with C linkage} to {pointer to function with C++ linkage} and vice ve
  • How to fetch the alt value from an img using vba
  • Delphi: Form becomes Frozen while assigning strings in thread
  • CDI: Injecting single instance works, but injecting Instance does not. Why?
  • How to grep for a specific pattern and print everything above and below that pattern until you reach
  • Calling java project from Mathematica
  • PHP file_exists() anomaly
  • SQL Server re-calculate or not?
  • Insertion large number of Entities into SQL Server 2012 [duplicate]
  • Watson Conversation - Why is the ANYTHING ELSE node not chosen
  • Create function that can pass a parameter without making a new component
  • Add reference to ASP.NET 5 Class Library from Framework 4.5 Class Library Project
  • aapt.exe'' finished with non-zero exit value 1
  • Why cepheus don't send int without quotes to orion?
  • Tamper-proof configuration files in .NET?
  • Code in Job's Script Block after Start-Process Does not Execute
  • Is playing sound in Javascript performance heavy?
  • how to save the state in userdefaults of accessory checkmark-iphone
  • MonoTouch: How to download pdf incrementally as indicated in the Apple slides “Building Newsstand Ap
  • print() is showing quotation marks in results
  • ImageMagick, replace semi-transparent white with opaque white
  • NHibernate Validation Localization with S#arp Architecture
  • Q promise. Difference between .when and .then
  • Insert into database using onclick function
  • Illegal mix of collations for operation for date/time comparison
  • Running a C# exe file
  • Knitr HTML Loop - Some HTML output, some R output
  • Can a Chrome extension content script make an jQuery AJAX request for an html file that is itself a
  • Getting 'uninitialized constant' error when using delegate in belongs_to in model
  • retrieve vertices with no linked edge in arangodb
  • Suggestions to manage Login/Logout transitions
  • Angular 2 constructor injection vs direct access
  • Java static initializers and reflection
  • Android Google Maps API OnLocationChanged only called once
  • UserPrincipal.Current returns apppool on IIS