C# console window problem with _getch() - c#

I have embedded a console window within my Windows application form using ะก#
I have an application that runs in the console window. my c# project is a GUI to display the output of this and also to send parameters to it.
Most is working fine except when a call to _getch() is made from my GUI to the console window it tends to freeze up the whole system.
anyone got any ideas why this would happen?
I can post code if need be.
Thank you

Odds are that _getch() is a blocking call.

The _getch() function won't return until the user presses a typing key on the keyboard. If this function is called from your program's main thread then this will stall the UI thread. It won't pump the message loop, your UI freezes when it no longer processes input events nor paints the windows. After a couple of seconds Windows puts the ghost window in place with "Not Responding" in the title bar.
While calling _getch() from a background thread will solve the problem, that's probably not going to be convenient. You can use _kbhit() to check if a keystroke is available. Calling _getch() after _kbhit() returns true won't block. Probably not convenient either. Trying to pump the message loop while _kbhit() returns false would technically be a solution, if it wasn't for the message loop living in the wrong code.
Note that you can type Ctrl+S in the console window to pause output, Ctrl+Q resumes it again. You'll still block the UI thread but at least you'll do it knowingly.

What does _getch() do. You can start the call in another thread if its blocking the UI thread.

Related

Dialog hangs when called from event

Using the CoreScanner Driver provided by Motorola, I'm trying to write a small winforms application that uses a barcode scanner. I'm able to interact with the scanner just fine, and properly register a call back for the OnBarcodeEvent(). In this callback, I have a Dialog that opens and displays a screen that the user needs to fill in. Shortly after the dialog is opened (using Show()), the program hangs. If I use ShowDialog(), the dialog works, but the dialog is blocking the OnBarcodeEvent event.
My guess to what is happening, is that since the dialog is getting created on the event thread, there is a race condition occurring when using Show(). Since Show() is non-blocking, the thread continues on after displaying the dialog and then dies out. Meanwhile my dialog just lost it's parent and locks up? Like i said... my best guess.
How can I remedy the situation? That is, How do I write my dialog so that it can be created within a thread not hang?
In the event, you should launch a different thread that will create your dialog form and show the form on it. You need to block this thread till form is visible - this is possible either by ShowDialog or alternately use one of Application.Run overload.
Yet another option would be to show the form on the UI thread (i.e. main application thread) - to do that, you need to call Invoke method on your main form from the event code. The invoke call should take the delegate that will show your dialog form non modally.
I have some experience with Motorola/Symbol Handheld-Devices (MC9090) and I guess the SDK will be similar.
It's hard to say without seeing the code, but my guesses:
your common not-UI thread problem - so make sure you open your dialog using UI thread
the native Motorola-driver is crashing - no kidding, this happened a lot to me - in my case (compact-framework on a WinCE device) this would not freeze the program but the scanner will not work/receive any messages before restarting the device
In order to fix this you should seperate the showing/handling of user-dialog away from the event and make sure you call this on the UI-thread (Control.InvokeRequired / Control.Invoke).

Exiting a C# winforms application

I have an application that imports data from Excel. However, when I run the winforms app and I intrupt the application, using System.Windows.Forms.Application.Exit(); I can still see the "MyAppName".vshost32.exe running in task manager.
When I exit the application in debug mode, the form closes, but the VS IDE is not "stopped".
How do I ensure the application ends correctly.
Your call to Application.Exit() is working fine. The MyAppName.vshost32.exe executable is a host for debugging purposes. It runs whilst you have a project open in Visual Studio, regardless of if there is an active debugging session.
Update: Ok, I misunderstood. The above is true, but you're probably having problems with hung threads in the background. You need to terminate your threads to make it close properly. Asher's answer covers this. If you're just trying to do a super-hacky quick-and-dirty kill, you can use the following (though I take no responsibility for side effects, since it's extremely hacky):
System.Diagnostics.Process.GetCurrentProcess().Kill();
The process doesn't terminate because it still has foreground threads running.
If you create threads in your application you need to mark them as background threads or make sure they terminate when you want the application to exit.
Have you tried the more brutal Environment.Exit() function?
Application.Exit() just sends a message saying to shutdown; if the message never gets processed (for whatever reason), the application will stay running indefinitely.
From the MSDN documentation of Application.Exit():
The Exit method stops all running message loops on all threads and closes all windows of the application. This method does not necessarily force the application to exit. The Exit method is typically called from within a message loop, and forces Run to return.
I had a similar problem caused by a third party tool that did not allow me to set the threads as Background. Polynomial had the right idea, but then syntax is like this:
System.Diagnostics.Process.GetCurrentProcess().Kill();

Waiting on Mainthread while continuing processing on UI

When working with console applications, Console.Readline relinquishes processing to the UI from the Main thread and only continues when an event, such as the pressing of the enter button is fired. How do I replicate this functionality (With a Window form as the UI in this case) in windows form application?
You cannot do this directly.
However, you can do it by calling Invoke, as I described here.
Use form.ShowDialog() instead of form.Show()
This will not stop the thread, but it will stop the user from doing other things in the UI until the window is closed.
Now that you have explained what you want to do...
It would be better to use a BackgroundWorker, keep the GUI active, but disabled and presenting a progress bar + cancel button, until done.

Why does my application not close on logoff/shutdown (c#/.net winforms)?

My winforms app isn't shutting down nicely when I log off/shutdown. I have a main form, whose Closing event is fired correctly, but there must be something else keeping my application around. If I check Application.OpenForms there's just my one main form.
The tricky bit, and where the problem probably lies, is that my application uses ShellWindows to hook into Internet Explorer, and occassionally opens up forms when IE events fire. It's after one or more of these forms has been opened and closed that my app stops closing on shutdown.
I think I'm cleaning up all form objects etc and calling FinalReleaseComObject() appropriately, but I guess there are references somewhere that are holding my process open. Is there any way to work out what it is that's stopping my app from closing gracefully?
An application will also stay open if there are threads running that have not been set to background. If you are creating any of your own threads, make sure that they are terminating appropriately.
If it is not critical that the thread finishes, set IsBackground to true. You can also call Abort on a thread to (somewhat)forcibly kill it.
The most likely cause is that you have a background thread hanging around that is not being closed when the main window of your application is closed. Depending on your settings and framework version background threads can keep an application alive when the main thread is terminated.
During shutdown windows asks every running app to terminate usually by sending a WM_QUIT to the main window on a process. WinForms will happily use this message to shutdown the main window but if any background threads are left the actual process could continue.
This is a really ugly way to do this, but if all you want to do is kill any thread that's hanging around, you can get all the threads running in your application with System.Diagnostics.Process.GetCurrentProcess.Threads, and then enumerate through them and call Thread.Join() or Thread.Abort() on them.
Just make sure to NOT call .Abort() on the main (UI) thread that you're working from (the one that receives the Closing event). So make sure to check that your current thread (System.Threading.Thread) is not the one you're aborting.

Automatically show loader on long operation

I'm trying to show a loader animation when my application it's blocked for more than 500ms.
I want that to be automatic, I don't want to add any piece of code before every long operation.
I know that in WinForms it was possible (I used this: https://snipplr.com/view/24851/), but It does not work in WPF.
I've found that I can do that with the mouse cursor(display Hourglass when application is busy)
I've tried to launch a window with a spinner.
I've found this answer (https://stackoverflow.com/a/21411656/10820863), that works detecting long operation.
Problem is that if I launch a window from a thread that is not the main one, I got a ThreadException because it's not the main thread. If I use Application.Current.Dispatcher.BeginInvoke
method, the window appears only when UI is not blocked anymore.
So, how can I automatically detect long operation and show a loading window/page/image/whatever if it lasts for more than 500ms?
[EDIT]
I don't want to add code to every long function, evaluating case for case which function can be long.
I'd prefer to have an automatic method that do that for me.

Categories