Go Back

Windows programs not responding

I have a number of programs which process down files.  they display a progress count, so are refreshing eth screen every 1 to 5 seconds, and sometimes several times a second.

But the application window title bar says "not responding"

Sometimes the whole application window greys out and if you click on the screen you can get a;



So users will just close the program or else ask to have their programs killed off as they are not responding

but even in the greyed out, not responding state, the progress count carries on updating the screen.

Thios doesn't happen on my own PC. 

This is running on a terminal server, which is windows server 2012.  Synergy 10.3.1b


I tried to attach a screen shot, but it said it was too big.  I can email it I anyone is interested

Any suggestions ?

 

14 Answers
5   | Posted by Gordon Ireland to Other on 9/27/2016, 8:08 PM
Bill Hawkins
Hi Gordon,  We also hit this problem with the RCC application.  As it was explained to me, the underlying problem is that Synergy is single threaded, so when it's busy doing background processing it's not updating the UI thread in the same way that a WinForm/WPF/etc. app does, and because the UI thread is not being pinged by the app, Windows thinks the app has hung and puts up the "not responding" message.  If the app continues to work in this mode, eventually Windows can just kill the process - even though it's still processing stuff just fine.
Fortunately (for us) almost 100% of our screen I/O went through application routines and did not do direct terminal updates.  So we were able to modify these routines to use a separate UI thread, and deal with the issue that way.  This approach is not for the feint of heart, but it worked for us.   (Note this solution only works for Synergy for .NET, not traditional Synergy.)

9/30/2016, 7:00 AM   1  
Gordon Ireland
Thanks Bill. This is a synergy.net application. I only get the problem when doing lengthy processing. Inteactive screens are fine. All such processes use a single progress coun routine, so I might just have to change that to solve the problem. Can you explain what needs done? It us just a display routine, currently using w_disp.

9/30/2016, 7:51 AM   1  
Mark Vinten
Hi Gordon,

It doesn't really matter whether it's Synergy.NET, Traditional Synergy or C++.  If you are actively using the current thread of the program to perform extensive data tasks, that same thread isn't available for responding to a UI.  There are two ways around this.

Option 1 - Use Multiple Threads.
Multi-Threading within your application can help by running an extensive task on a separate thread.  As you are using .NET this is an option that is available to you.  However, you have to be careful around deadlocks were two threads are both trying to access something and effectively lock the other out.  You also need to ensure that you are properly handling data in common areas.  If you use a static object, one thread may be updating the values whilst another is reading them so if there are dependant properties there can be a timing issue.  The best way to get around this is to pass any status data via call backs rather than rely on fixed objects.

Option 2 - Use Multiple Programs
Using multiple programs gives you the advantage that killing the sub process would not kill your UI.  However, it does present the more complicated problem of reporting the output.  This can be handled in multiple ways using either a console subprogram with input/output capturing or using a messaging system like named pipes to transfer information both ways. 

Examples
Below are some real world examples summarised to give you some idea of what we use and when.

Program 1 runs on a users desktop spawns a process every 30 seconds to generate the occasional output file for multiple companies.  This uses option 1 since its a simple program and if it crashes can be quickly restarted by the end user.  So it has a separate thread handle each companies generation process and reports their progress via events and cross-thread posting.  The main UI simply reports what is happening and little more so always remains responsive. 

Program 2 is spawn via Task Scheduler as there are multiple time schedules dependant on days of the week.  It is a very important program that generates invoices, creates emails, etc.  If the task is already running, it simply restarts processing those which are already completed.  As such, that uses Option 2 to be as stable as possible since it contacts many different systems and a single crash in the main program would stop everything running.  Now, if the crash occurs, it is reported and on the next cycle automatically started again since our processes handle picking up where they left off.  It also utilises named pipes to pass data back and forth including updating runtime parameters in a live fashion allowing extra debugging to be instantly turned on/off from the UI.

What to look at
In .NET, you would take advantage of the System.Threading namespace to provide multiple threads or the BackgroundWorker system depending on the style of threads you want.  When working with WPF, you also have Dispatcher.  You need to be careful about which Timers you use as well since there are Dispatcher-based timers as well as generic system ones.  You can also make use of the new Async system in C# but I'm not entirely sure where Synergy.NET lies in that world as I haven't used it for a while.

If you are working with threads, be very careful about which objects and methods are thread-safe and which are not.  A non-thread safe thread will update a value without a lock.  This leads to race conditions were two threads update the same field/variable at the same time and the resulting value is not the one that they expect.  A race condition can also occur with locks, so be very careful about where you lock and why.  A lock should be obtained for the shortest possible time.

I've already waffled on about loads here, so I would just suggest learning about multi-threading a start there since Option 2 requires you to have the knowledge of Option 1 in the first place.

9/30/2016, 11:18 AM   1  
Gordon Ireland
Hi Mark
Its mainly traditional synergy application, running under synergy.net.   Currently only the printing uses objects.

There are hundreds of programs involved, and many of the option happen when the user is reading data to display in a report on enquiry, so just spawning of to a background process is not an option.
 
I have one standard routine which displays a progress count windows, which refreshes the screen every few seconds.  That is the routine I need to keep alive.

It uses low level windows, without any objects or methods involved

Any suggestions ?

9/30/2016, 11:40 AM   0  
Mark Vinten
As far as I am aware, if you are in Synergy.NET you are not running Traditional Synergy.  If the output generates a .EXE, that is .NET but if it generates a .DBR  that would be Traditional.  .NET can handle most of the code that Traditional I think, but there are limitations some of which the PSG have come across and mentioned in various blogs, reports, emails or posts.

The other way to check is whether you have access to any of the .NET namespaces directly?  If so, you are running .NET not Traditional.  If you are completely running traditional, I'm not sure there are any threading options available to you.  There are certainly no language keywords to make them available so it would require writing a C DLL to attempt to handle that for you and even then may not work if the DBR is truly an STA (Single Thread Apartment).

If you are in .NET, you can make use of the rest of the features of .NET like threading but you'll have to be careful about handling errors or output in any thread so that it makes its way back to the main thread.  That also means that you might be utilising the routines similar to Traditional Synergy in name but their functionality has been converted behind the scenes to the .NET world.

9/30/2016, 12:02 PM   0  
Gordon Ireland
Sorry for confusing you.  the code was traditional syerngy

The mainlines were all converted to subroutines and placed in a series of projects, which builds to a single.net solution

However, it is still full of all the old ONERRORs etc, and dates back to the 1970s in places.

The idea is to modernise it, but right now I need to get my PrintProgress subroutine to display to the window differently.   It is a very simple routine, written using low level windows

 

9/30/2016, 12:25 PM   0  
Mark Vinten
Short of spawning another DBR running your update code in the background, I don't think there is going to be much you can do under Traditional Synergy.  This was always a problem but Windows has got a lot more talkative about a window not responding these days and making it a lot easier to kill.

If the programs are all subroutines, can you not spawn another DBR to do the background work ?

9/30/2016, 1:04 PM   0  
Gordon Ireland
No, the churning around is usually to create a print file to preview on screen.  It might only take a minute to create the output.  So the process has to stay connected as the users wants to do something with the result, such as view, search o rprint.

I'm interested to see what Bill's solution is
 

9/30/2016, 2:07 PM   0  
Bill Hawkins
Our wrapper routines had to wrap a lot of the W_* routines, anything that needed the Synergy container form and xcall flags - basically anything that interacted with the UI.  While we didn't wrap the explicit Synergy calls, we wrapped our application foundation routines that used these Synergy calls.  If you contact me directly, we can discuss our solution to see if it's appropriate for you.  If so, I'll put together an example program without all of our application specific code.  If you go this route, your whole application has to implement this, not just the progress window.  It will not work properly unless you go the whole 9 yards.
FYI, it doesn't need to be a long running program, you can generated this issue in about 5-6 seconds.  We were able to reproduce the "not responding" issue by running the app and get it into the processing steady state.  Click outside the Synergy window, so that it loses focus. Wait a few seconds, click on the Synergy window.  Wait a few more seconds and click on the Synergy window again, and you should be in a "not responding" mode.

9/30/2016, 3:52 PM   0  
Gordon Ireland
Very keen to follow up with you bill. My emal is g_ireland@btinternet.com

 

9/30/2016, 5:10 PM   0  
Chris Clarke
hi,
two options, make the code multi-threaded as suggested or call out to this Windows API
 Private Declare Sub DisableProcessWindowsGhosting Lib "User32.dll" ()

This will disable the window ghosting for your application, granted your application wont respond during these processes that hog the UI thread but at least your customers don't think its crashed, this is often easier than refactoring all your code :-)

Regards
Chris

10/20/2016, 4:49 PM   1  
Gordon Ireland
Hi Chris

So can I just do that at the start of the application when I am initialising my low level windows - defining size, colour etc ?

Do I just drop that line into my synergy code or do I have to wrap it up in something ?   If so, could I b echeeky and ask for some sample code ?

Gordon

10/20/2016, 5:06 PM   0  
Chris Clarke
Hi Gordon,
When we do this for winforms apps, yes we just call it at the beginning of the program.  I couldn't tell you the syntax to do this in synergy, in C# you would add the code below to your main form or startup class:
[DllImport("user32.dll")]
public static extern void DisableProcessWindowsGhosting();
Then you call the method on startup.  If you can't work it out in Synergy then you could create a small C# assembly with a single class and a static method to just call this API.

Regards
Chris


 

10/24/2016, 9:00 AM   0  
Gordon Ireland
Thanks to Chris Clarke and Bill Hawkins, I have implemented a simple solution which works.

In my main program I included an import :

import System.Runtime.InteropServices

I wrote a small class

public class ghosting
{DllImport("user32.dll")}
public static method DisableProcessWindowsGhosting ,void
endparams
proc
endmethod
endclass



I called a method within the class at the start of the application.

ghosting.DisableProcessWindowsGhosting()


Job done !
 

10/31/2016, 7:02 PM   0  
Please log in to comment or answer this question.