I have a large WPF app with few threads ( all threads use dispatcher.invoke to update the GUI) and many grids and controls. At any give time only 2 or three grids are visible so the user can interact with the controls. I also have an external device which sends a signal to my app and I then update the GUI so the user knows the signal was fired.
I do the update through a dispatcher since the signal detection is on another thread. So everything is fine until intermittently it takes 5 minutes for the dispatcher.invoke with normal priority to call my method. when this happens as soon as I click the GUI then method gets called immediately. So it seems that message pump is asleep or hung and as soon as I click on the GUI it wakes up and process my message. I have done this several times so I am sure that message queue wakes up upon refreshing the GUI.
So is this a bug in WPF message pump queue where it occasionally goes to sleep and wakes up when the GUI is refreshed? or what is the reason for this behavior and what to do about it.
Thanks in advance
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 am developing an interface in my C# 4.0 winform application, to fire some sms in bulk. Each message content is different so that I have to fire messages one by one. I have a form from where the end user can shoot smss, it may be more than a thousand.
I want to manage a queue. If the user shoots a sms then it will be submitted to the queue and the queue will send sms one by one.
So I have to create a form to manage the queue. The problem is that I want my application to work normally and in the background the queue sends sms.
So how can I achieve this task? I have tried BackGroundWorker, but I don't know how to maintain a separate thread with a form.
All forms must be on the UI thread. The sending of the SMS should be performed by the BackgroundWorker.DoWork event. The updating of the form is then done by BackgroundWorker.RunWorkerCompleted event.
The UI thread is main thread of the application for SWF (winforms)
If you are using C# 4.0 or above, you may also want to investiage the Take Parallel Library (http://msdn.microsoft.com/en-us/library/dd460717.aspx). But I would first get BackgroundWorker implementation to work. Then use TPL to send simultaneous SMS. Could really speed things up.
you have to create one thread (called worker thread) which runs for the life your application.
you have to have a queue or even better a concurrent queue http://msdn.microsoft.com/en-us/library/dd267265.aspx
the worker thread wait when an item (sms) appears in the queue, takes that item and do its work.
the UI is completely decoupled from that work.
this is most basic use of the class Thread.
Background worker is least suitable solution. obviously you can use a washing machines to build a house but most people use bricks.
You can start Thread then create new instance of form on it (with no parent) and then start message loop (such code located in Main method of project's template).
Remember, any form (generally any GDI object) can be used only on thread that creates it. E.g you can't create child form on another thread, then parent's. Every GUI thread must run message loop.
apologies if I don't explain this clearly, but I'm writing an app which is causing me some problems with threading.
I have a UI which starts a System.Timers.Timer. Each time this timer elapses it triggers a workflow which opens a progress screen. To prevent another workflow starting before the last one has finished it locks an object on the main form.
This progress screen starts and reports the progress of, some file copying using FileCopyEX.
The problem I'm having is that the progress screen does not display until after the work flow has been completed.
Hopefully this will make it clearer:
Main Form
|
Timer Elapses
|
WorkFlow Starts
|
Progress Screen opens (errors which occur go back to the previous)
|
File copying occurs (progress reported back to progress screen)
If no errors, returns to main screen before next tick.
Until now I've only implemented very simple threading, so I'm not sure how best to implement this. I've tried starting the workflow on a BackGroundWorker to seperate it from the UI thread but it behaves the same.
Thanks
I suggest that you read about the BackgroundWorker. This has hooks for reporting progress.
Remember that system timers invoke its event handler on a non-UI thread. Whenever, you do something with the UI you must be on the UI thread.
Without the code I can only guess at the cause, but the likely reason is that the Progress window needs the UI to be pumping messages to appear - i.e. the UI thread needs to be running.
If the UI thread is busy running your workflow, then it won't get around to processing the displaying of your window until after that. You need to separate your flow so that the progress window is on your UI thread and the workflow is on a background thread.
Hope that makes sense!
(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.