I'm developing a Windows application to run in the background (for a long running process).
Application shows process status by a NotifyIcon tool tip.
I added a ContextMenu control to the NotifyIcon tool tip control. Whenever the application is idle (not doing any work), the context menu works fine, but during the running of a process the context menu hangs.
All processes are running in different threads. Can anyone tell me how I can make a smooth context menu for a long running background process?
The exact same rules apply to a program that has a NotifyIcon as a program that uses Window or Form to show a user interface. NotifyIcon sends notifications to the main thread of the process, the one on which you called Application.Run(). And if that main thread is busy with other tasks, like "running of a process" then the NotifyIcon goes catatonic. It is trying to send the notification but your main thread isn't listening since it is busy executing that "process".
And you'll have to solve this the exact same way as in a regular gui program, you have to run the processing code on a worker thread. Use the standard .NET solutions, like BackgroundWorker, Task or the async/await keywords. Or spin your own with Thread or ThreadPool.
If you are already doing this, it isn't clear from the question, then watch out for, say, a BackgroundWorker that calls ReportProgress too often and still gets the main thread bogged down.
Related
I have read a lot on threading but can't figure out a way to make this one work right. So it should really be obvious how to do this as it usually is with me (always missing the obvious) :p
Here's my problem (BTW, am working with WPF in C#):
I have a long running process i'm running on a separate thread while the UI stays responsinve and showing evolution. However, mid-process, i need to ask the user to confirm a value before proceeding. That's what i can't figure out, cause the window to confirm the value must be run in the UI thread and still return the value to the work thread so it can continue it's work.
So...
Long running process beeing run in work thread
Work thread waits for UI Thread
UI thread shows the confirmation window
User confirms/fixes value and closes the confirmation window
UI thread sends result from confirmation window to work thread
work thread gets values from UI Thread (value was changed by user? to what?)
work thread continues long running process
Work thread gets values from confirmation window
I've already the work thread working well using ThreadPool - although am open to using threading in different ways (NET 4.5). Problem i am having is that if i send the confirmation window part to dispatcher my work thread won't wait for the results from the confirmation window. If i don't put in the dispatcher i get an exception about not beeing in an STA thread when the window constructor is called.
Any ideas welcome
You probably don't want to block the worker thread waiting on UI (not saying you couldn't do it, but it would be messy).
A much simpler solution would be to split up your process into two threads; one that runs pre-user input, and one that runs after. You would prompt the user upon the first thread's completion (via a callback or event).
Something like (pseudo-code)
InitialThreadObject.Completed += () =>
{
PromptForUI();
SecondThreadObject.Start();
}
InitialThreadObject.Start();
Obviously you would choose the completion notification mechanism based on your current code.
I'm new to developing Winform application (using C# .NET)
My application will freeze and sometimes even showing "not responding" when there are too many operations running behind, especially when it involves a lot of data reading/writing to/from database. The application did NOT crash though, it just freeze until the all code behind were finish executing.
My question is, how do I "unfreeze" the application. For example, the user can still click the "cancel" button to terminate whatever the operation is running, or show a progress bar or something like that?
Your application freezes because it has single thread, which is responsible both for drawing UI and doing other 'heavy' operations (reading/writing to database). When thread is busy with database, it cannot refresh UI. You should perform 'heavy' operations in background thread(s). Thus main thread will be responsible only for refreshing UI and it will be always ready to do that. Use BackgroundWorker component to run some operations on background threads.
Suggested reading: BackgroundWorker Class Sample for Beginners and How to: Use a Background Worker
A windows application will stop working if you are using a System.Timers.Timer.
To fix this, change System.Timers.Timer by System.Windows.Forms.Timer
Greetings
I'm trying to figure out why the application process lingers in Task Manager after the application is closed and the window disappears.
When I get VS to attach to the zombie process and break all, the threads window shows that the main thread is still alive, and a number of worker threads as well.
Some questions:
Are worker threads necessarily background threads? If not, how do I identify the background threads as I didn't see such a column in the window?
Do I simply double-click on each thread in the thread window, and watch the Thread.IsBackgroundThread value?
When I click on the main thread, the debugger doesn't show a call stack. How
do I identify where the main thread is stuck?
I would strongly sugest you tu use WinDbg. It is not a visual debugger though it is much more powerful.
Surely I will figure you out.
To list all threads in a process use: ~.
To switch to a certain thread ~thread_ids.
To see stak of curent thread !clr_stack.
Brief tutorial.
http://www.codeproject.com/KB/debug/windbg_part1.aspx
Also try in google "Debuging Asp.net with windbg"
(WPF) We have been asked to build a little window that pops up when the app is busy (instead of or in addition to a wait cursor). We put a textblock in the window, and a ProgressBar with IsIndeterminate = true.
We call show on the little window, and then start up our long-running process, calling Close on the little window when we are through. However, during the long-running process, the ProgressBar does not show any activity, and the little window shows (Not Responding) in its title.
Is this even possible? A better idea?
You need to look into using another thread (or multiple threads) to do the heavy processing that could take longer than 100ms (100ms and above can cause this 'hanging' appearence before 'Not Responding' appears.)
You could create a new thread using a BackgroundWorker
object and subscribe to the OnProgressChanged event to indicate a progress bar update. This does not however get around the problem of accessing the main (UI) threads Progress Bar. You would have to check if an Invoke is required and then invoke a piece of code responsible for updating the Progress Bar.
Here is a StackOverflow question that shows a nice Extension Method in the accepted answer for invoking a method call on a control:
Invoking
Hopefully that helps!!
The problem is most likely that whatever is causing the app to be "busy" is being run in the main thread of the app. So, the app stops responding, including responding to layout and painting requests from the OS. So, when the app is "busy", it's too busy to paint the new window.
The solution is to move as much "heavy lifting" as possible into background threads, so the main thread and thus the UI remain responsive.
K I am looking at a primarily single thread windows forms application in 3.0. Recently my boss had a progress dialogue added on a separate thread so the user would see some activity when the main thread went away and did some heavy duty work and locked out the GUI.
The above works fine unless the user switches applications or minimizes as the progress form sits top most and will not disappear with the main application. This is not so bad if there are lots of little operations as the event structure of the main form catches up with its events when it gets time so minimized and active flags can be checked and thus the dialog thread can hide or show itself accordingly.
But if a long running sql operation kicks off then no events fire. I have tried intercepting the WndProc command but this also appears queued when a long running sql operation is executing. I have also tried picking up the processes, finding the current app and checking various memory values isiconic and the like inside the progress thread but until the sql operation finishes none of these get updated. Removing the topmost causes the dialog to disappear when another app activates but if the main app is then brought back it does not appear again.
So I need a way to find out if the other thread is minimized or no longer active that does not involve querying the actual thread as that locks until the sql operation finishes.
Now I know that this is not the best way to write this and it would be better to have all the heavy processing on separate threads leaving the GUI free but as this is a huge ancient legacy app the time to re-write in that fashion will not be provided so I have to work with what I have got.
Any help is appreciated
It sounds as if the long running operation is bound to the progress dialog? That's usually a bad idea and I wonder whether the progress can be showed at all.
However you should consider using a BackgroundWorker for your long running operations. So your GUI (the main form as well as the progress dialog stays alive).
This way you should be able to send the minimize event of the main form to the progress dialog which can react to it instantly.
Btw. the BackgroundWorker supports progress reports on its own.