I think I need some help understanding the Dispatcher Queue.
When new work arrives it gets added at the beginning of the dispatcher queue and when the Dispatcher wants to process a working item it gets removed from the beginning.
In more general terms: If there is work it gets stored in a FIFO manner inside the queue and processed as long there is no work left.
The MSDN documentation here is referring to a loop and a frame:
The Dispatcher processes the work item queue in a loop. The loop is referred to as a frame.
But where is a loop in this context ? For me a loop is something that iterates over something and when it reaches the end it starts over again.
And what's the concept of a frame ? According to the MSDN documentation a frame is a punch of working items inside the queue ? If that's true how should the static method Disptatcher.PushFrame() be used ?
And the most interesting question is whether there is any way to get the current state of the queue especially how many items are in the queue.
Does it hold if a method that has been invoked before (and therefor put into the Dispatcher queue) gets executed that it is then removed from the queue immediately or does it last inside for another period of time ?
I know, So many questions :-)
There's very little documentation surrounding the Dispatcher, so you'll have to disassemble around a bit to know about the inner workings.
A dispatcher is basically something which performs work around the application's Message Pump. The one in question sits on top of the windows message loop.
As a consequence, there can only be one application Dispatcher - the global dispatcher object accessible by Application.Current.Dispatcher. Other dispatchers are possible by accessing Dispatcher.CurrentDispatcher, which according to the documentation
Gets the Dispatcher for the thread currently executing and creates a
new Dispatcher if one is not already associated with the thread.
However, calling Run on this new dispatcher will be blocking.
When you do a Dispatcher.PushFrame, it pushes an inner execution loop into the Dispatcher - that's the general idea of a frame. Anything that inherits from DispatcherObject such as DispatcherFrame will have its dispatcher set to the current one. We can verify this by looking at its constructor.
private Dispatcher _dispatcher;
protected DispatcherObject()
{
this._dispatcher = Dispatcher.CurrentDispatcher;
}
Of course, having a simple event loop isn't enough - there are times when you need to subvert the current event loop to force other work to be done. And that's why you have a DispatcherFrame. This is what actually constitutes the event loop. When you push a frame into the Dispatcher, this is what happens:
while (frame.Continue)
{
if (!this.GetMessage(ref msg, IntPtr.Zero, 0, 0))
{
break;
}
this.TranslateAndDispatchMessage(ref msg);
}
It is in the TranslateAndDispatchMessage that the prioritized queue in the Dispatcher gets evaluated, after a message is taken out.
If an operation takes a long time to run on the dispatcher, it temporarily stops the event loop, and because it doesn't respond to signalling, the application seems like it stops responding.
Here's an article which uses a frame to force the UI to respond by allowing the event loop to run shortly.
As for accessing the queue, as it is, there is no way to know the state of the queue outside of the Dispatcher. This is an internal detail, and it's reasonable that it's not exposed.
Related
In my application I have a queue which fires notifications whenever there are any changes to the queue, but sometimes it happens that when there are simultaneous operations on the queue event handler that it fires multiple times and that's okay, but what I don't want is,...
Below is the code for the event handler:
private async void NotificationQueue_Changed(object sender, EventArgs e)
{
if (!IsQueueInProcess)
await ProcessQeueue();
}
In ProcessQueue method I am setting IsQueueInProcess to true and whenever it gets completed it is set to false. Now, the problem is that whenever multiple event notifications fire simultaneously multiple ProcessQeueue methods start executing, which I don't want. I want to make sure that there will be only one execution of ProcessQeueue at any given time.
Given your statement that this event is raised whenever there are any changes to the queue, and that the queue can be used concurrently (i.e. there are multiple producers adding things to the queue), it seems likely to me that the best way to address this would be to abandon the event-based behavior altogether. Instead, using BlockingCollection<T>, with a thread dedicated to processing the queue via GetConsumingEnumerable(). That method will block the thread as long as the queue is empty, and will allow the thread to remove and process items in the queue any time any other thread adds something to it. The collection itself is thread-safe, so using that you would not require any additional thread synchronization (for the handling of the queue, that is…it's possible processing an item involves thread interactions, but there's nothing in your question that describes that aspect, so I can't say one way or the other anything about that).
That said, taking the question literally, the simplest approach would be to include a semaphore:
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1);
private async void NotificationQueue_Changed(object sender, EventArgs e)
{
if (_semaphore.Wait(0))
{
await ProcessQueue();
_semaphore.Release();
}
}
The above attempts to acquire the semaphore's lock. With a timeout of 0 milliseconds, it will return immediately even if the semaphore could not be acquired. The return value indicates whether the semaphore was successfully acquired or not.
In this way, as long as there is no outstanding queue-processing operation, the current event handler invocation can acquire the semaphore and will call the ProcessQueue() method. When that operation completes, the continuation will release the semaphore. Until that happens, no other invocation of the event handler will be able to acquire the semaphore, and thus will not initiate processing of the queue.
I'll note that nothing here guarantees a solution to threads racing with each other that would ensure the queue is always either empty, or always has some processing operation acting on it. That's up to you, to ensure that the ProcessQueue() method has the synchronization needed to guarantee that if any thread has modified the queue and caused this event to be raised, that that thread will not fail to initiate another round of processing should the first round not be able to observe the change.
Or put another way, you need to make sure that for any thread that is going to raise that event, either its change to the queue will be observed by the current processing operation, or that thread will initiate a new one.
There's not enough context in your question for anyone to be able to address that concern specifically. I will just point out that it's a common enough thing for someone to overlook when trying to implement this sort of system. IMHO, all the more reason to just have a dedicated thread using BlockingCollection<T> to consume elements added to the queue. :)
See also the related question How to avoid reentrancy with async void event handlers?. This is a slightly different question, in that the accepted answer causes each invocation of the event handler to result in the operation initiated by the event handler. Your scenario is simpler, since you simply want to skip initiation of a new operation, but you may still find some useful insight there.
I agree with Peter that abandoning event-based notifications is the best solution, and that you should move to a producer/consumer queue. However, I recommend one of the TPL Dataflow blocks instead of BlockingCollection<T>.
In particular, ActionBlock<T> should work quite nicely:
private readonly ActionBlock<T> notificationQueue = new ActionBlock<T>(async t =>
{
await ProcessQueueItem(t);
});
By default, TPL Dataflow blocks have a concurrency limit of 1.
Suppose you are permanently invoking a method asynchronously onto the UI thread/dispatcher with
while (true) {
uiDispatcher.BeginInvoke(new Action<int, T>(insert_), DispatcherPriority.Normal, new object[] { });
}
On every run of the program you observe that the GUI of the application begins to freeze after about 90 seconds due to the flood of invocations (time varies but lies roughly between 1 and 2 minutes).
How could one exactly determine (measure ?) the point when this overloading occurs in order to stop it early enough ?
Appendix I:
In my actual program I don't have an infinite loop. I have an algorithm that iterates several hundred times before terminating. In every iteration I am adding a string to a List control in my WPF application. I used the while (true) { ... } construct because it matches best what happens. In fact the algorithm terminates correctly and all (hundreds) strings are added correctly to my List but after some time I am loosing the ability to use my GUI until the algorithm terminates - then the GUI is responsive again.
Appendix II:
The purpose of my program is to observe a particular algorithm while it's running. The strings I am adding are log entries: one log string per iteration. The reason why I am invoking these add-operations is that the algorithm is running in another thread than the UI thread. To catch up with the fact that I can't do UI manipulation from any thread other than the UI thread I built some kind of ThreadSafeObservableCollection (But I am pretty sure that this code is not worth posting because it would detract from the actual problem what I think is that the UI can't handle the repeatedly and fast invocation of methods.
It's pretty straight forward: you are doing it wrong by the time you overload the user's eyeballs. Which happens pretty quickly as far as modern cpu cores are concerned, beyond 20 updates per second the displayed information just starts to look like a blur. Something the cinema takes advantage of, movies play back at 24 frames per second.
Updating any faster than that is just a waste of resources. You still have an enormous amount of breathing room left before the UI thread starts to buckle. It depends on the amount of work you ask it to do, but typical is a x50 safety margin. A simple timer based on Environment.TickCount will get the job done, fire an update when the difference is >= 45 msec.
Posting that often to the UI is a red flag. Here is an alternative: Put new strings into a ConcurrentQueue and have a timer pull them out every 100ms.
Very simple and easy to implement, and the result is perfect.
I've not used WPF--just Windows Forms, but I would suggest that if there is a view-only control which will need to be updated asynchronously, the proper way to do it is to write the control so that its properties can be accessed freely from any thread, and updating a control will BeginInvoke the refresh routine only if there isn't already an update pending; the latter determination can be made with an Int32 "flag" and Interlock.Exchange (the property setter calls Interlocked.Exchange on the flag after changing the underlying field; if the flag had been clear, it does a BeginInvoke on the refresh routine; the refresh routine then clears the flag and performs the refresh). In some cases, the pattern may be further enhanced by having the control's refresh routine check how much time has elapsed since the last time it ran and, if the answer is less than 20ms or so, use a timer to trigger a refresh 20ms after the previous one.
Even though .net can handle having many BeginInvoke actions posted on the UI thread, it's often pointless to have more than update for a single control pending at a time. Limit the pending actions to one (or at most a small number) per control, and there will be no danger of the queue overflowing.
ok, sorry for the bad link before in the comments, but I kept reading and maybe this will be of help:
The DispatcherOperation object returned by BeginInvoke can be used in several ways to interact with the specified delegate, such as:
Changing the DispatcherPriority of the delegate as it is pending execution in the event queue.
Removing the delegate from the event queue.
Waiting for the delegate to return.
Obtaining the value that the delegate returns after it is executed.
If multiple BeginInvoke calls are made at the same DispatcherPriority, they will be executed in the order the calls were made.
If BeginInvoke is called on a Dispatcher which has shut down, the status property of the returned DispatcherOperation is set to Aborted.
Maybe you can do something with the number of delegates that you are waiting on...
To put supercat's solution in a more WPF like way, try for an MVVM pattern and then you can have a separate view model class which you can share between threads, perhaps take locks out at apropriate points or use the concurrent collections class. You implement an interface (I think it's INotifyPropertyChanged and fire an event to say the collection has changed. This event must be fired from the UI thread, but only needs
After going through the answers provided by others and your comments on them, your actual intent seems to be ensuring that UI remains responsive. For this I think you have already received good proposals.
But still, to answer your question (how to detect and flag overloading of UI thread) verbatim, I can suggest the following:
First determine what should be the definition of 'overloading' (for e.g. I can assume it to be 'UI thread stops rendering the controls and stops processing user input' for a big enough duration)
Define this duration (for e.g. if UI thread continues to process render and input messages in at-most 40ms I will say it is not overloaded).
Now Initiate a DispactherTimer with DispatcherPriority set according to your definition for overloading (for my e.g. it can be DispatcherPriority.Input or lower) and Interval sufficiently less than your 'duration' for overloading
Maintain a shared variable of type DateTime and on each tick of the timer change its value to DateTime.Now.
In the delegate you pass to BeginInvoke, you can compute a difference between current time and the last time Tick was fired. If it exceeds your 'measure' of overloading then well the UI thread is 'Overloaded' according to your definition. You can then set a shared flag which can be checked from inside your loop to take appropriate action.
Though I admit, it is not fool proof, but by empirically adjusting your 'measure' you should be able to detect overloading before it impacts you.
Use a StopWatch to measure minimum, maximum, average, first and last update durations. (You can ouput this to your UI.)
Your update frequency must be < than 1/(the average update duration).
Change your algorithm's implementation so that it iterations are invoked by a multimedia timer e.g. this .NET wrapper or this .NET wrapper. When the timer is activated, use Interlocked to prevent running a new iteration before current iteration is complete. If you need to iterations on the main, use a dispatcher. You can run more than 1 iteration per timer event, use a parameter for this and together with time measurements determine how many interations to run per timer event and how often you want the timer events.
I do not recommend using less than 5mSec for the timer, as the timer events will suffocate the CPU.
As I wrote ealier in my comment, use DispatcherPriority.Input when dispatching to the main thread, that way the UI's CPU time isn't suffocated by the dispatches. This is the same priority the UI messages have, so that way they are not ignored.
We have an implementation for an Ultrasound machine application current where the Ultrasound object is created on the UI's thread. A Singleton implementation would have been good here, but regardless, isn't.
Recently, the set methods changed such that they automatically stop and restart the ultrasound machine, which can take between 10-100ms depending on the state of the machine. For most cases, this isn't too bad of a problem, however it's still causing the UI thread to block for 100ms. Additionally, these methods are not thread-safe and must be called on the same thread where the object was initialized.
This largest issue this is now causing is unresponsive buttons in the UI, especially sliders which may try to update variables many times as you slide the bar. As a result, sliders especially will stutter and update very slowly as it makes many set calls through databound propeties.
What is a good way to create a thread specifically for the creation and work for this Ultrasound object, which will persist through the lifetime of the application?
A current temporary workaround involves spawning a Timer, and invoking a parameter update once we have detected the slider hasn't moved for 200ms, however a Timer would then have to be implemented for every slider and seems like a very messy solution which solves unresponsive sliders, but still blocks the UI thread occasionally.
One thing that's really great about programming the GUI is that you don't have to worry about multiple threads mucking things up for you (assuming you've got CheckForIllegalCrossThreadCalls = true, as you should). It's all single-threaded, operating by means of a message pump (queue) that processes incoming messages one-by-one.
Since you've indicated that you need to synchronize method calls that are not written to be thread-safe (totally understandable), there's no reason you can't implement your own message pump to deal with your Ultrasound object.
A naive, very simplistic version might look something like this (the BlockingCollection<T> class is great if you're on .NET 4.0 or have installed Rx extensions; otherwise, you can just use a plain vanilla Queue<T> and do your own locking). Warning: this is just a quick skeleton I've thrown together just now; I make no promises as to its robustness or even correctness.
class MessagePump<T>
{
// In your case you would set this to your Ultrasound object.
// You could just as easily design this class to be "object-agnostic";
// but I think that coupling an instance to a specific object makes it clearer
// what the purpose of the MessagePump<T> is.
private T _obj;
private BlockingCollection<Action<T>> _workItems;
private Thread _thread;
public MessagePump(T obj)
{
_obj = obj;
// Note: the default underlying data store for a BlockingCollection<T>
// is a FIFO ConcurrentQueue<T>, which is what we want.
_workItems = new BlockingCollection<Action<T>>();
_thread = new Thread(ProcessQueue);
_thread.IsBackground = true;
_thread.Start();
}
public void Submit(Action<T> workItem)
{
_workItems.Add(workItem);
}
private void ProcessQueue()
{
for (;;)
{
Action<T> workItem = _workItems.Take();
try
{
workItem(_obj);
}
catch
{
// Put in some exception handling mechanism so that
// this thread is always running. One idea would be to
// raise an event containing the Exception object on a
// threadpool thread. You definitely don't want to raise
// the event from THIS thread, though, since then you
// could hit ANOTHER exception, which would defeat the
// purpose of this catch block.
}
}
}
}
Then what would happen is: every time you want to interact with your Ultrasound object in some way, you do so through this message pump, by calling Submit and passing in some action that works with your Ultrasound object. The Ultrasound object then receives all messages sent to it synchronously (by which I mean, one at a time), while operating on its own non-GUI thread.
You should maintain a dedicated UltraSound thread, which creates the UltraSound object and then listens for callbacks from other threads.
You should maintain a thread-safe queue of delegates and have the UltraSound thread repeatedly execute and remove the first delegate in the queue.
This way, the UI thread can post actions to the queue, which will then be executed asynchronously by the UltraSound thread.
I'm not sure I fully understand the setup, but here is my attempt at a solution:
How about having the event handler for the slider check the last event time, and wait for 50ms before processing a user adjustment (only process the most recent value).
Then have a thread using a while loop and waiting on an AutoResetEvent trigger from the GUI. It would then create the object and set it?
I have a WinForm drawing a chart from available data.
I programmed it so that every 1 secong the Winform.Timer.Tick event calls a function that:
will dequeue all data available
will add new points on the chart
Right now data to be plotted is really huge and it takes a lot of time to be executed so to update my form. Also Winform.Timer.Tick relies on WM_TIMER , so it executes in the same thread of the Form.
Theses 2 things are making my form very UNresponsive.
What can I do to solve this issue?
I thought the following:
moving away from usage of Winform.Timer and start using a System.Threading.Timer
use the IsInvokeRequired pattern so I will rely on the .NET ThreadPool.
Since I have lots of data, is this a good idea?
I have fear that at some point also the ThreadPool will be too long or too big.
Can you give me your suggestion about my issue?
Thank you very much!
AFG
It is a good idea to move the fetching of the data to a Thread. You can use a BackgroundWorker that gets the data in an endless loop and
use the UpdateProgress event to update the chart. This takes care of the InvokeRequired business
Use a Sleep(remainingTime) inside the loop to get a desired frequency.
It is quite unlikely you'll be ahead by using a background timer. Your chart control almost certainly requires it to be updated from the same thread is was created on. Any kind of control that has a visible appearance does. Which requires you to use Control.BeginInvoke in the Elapsed event handler so that the update code runs on the UI thread. Dequeueing data isn't likely to be expensive, you will have actually have made it slower by invoking. And still not have taken the pressure off the UI thread.
You'll also have a potentially serious throttling problem, the timer will keep on ticking and pump data, even if the UI thread can't keep up. That will eventually crash your program with OOM.
Consider instead to make the code that updates the chart smarter. A chart can only display details of the data if such details are at least a pixel wide. Realistically, it can only display 2000 pixels with useful information. That's not much, updating 2000 data points shouldn't cause any trouble.
I would go with a System.Timers.Timer over a BackgroudWorker in an endless loop.
The BackgroundWorker is executed from a ThreadPool and is not meant to run for the lifetime of your application.
Motivation for System.Timers.Timer:
Each elapsed event is executed from a ThreadPool, won't hang your UI thread.
Using a combination of locks and enabling/disabling the timer we can get the same frequency as if we did a Thread.Sleep(xxx) in an endless loop.
Cleaner and more obvious as to what you are trying to achieve
Here's my suggestion:
Disabling the timer at the beginning of the method, then re-enabling it again at the end, will cater for the case where the amount of work done in the elapsed event takes longer than the timer interval. This also ensures the timer between updates is consistent. I've added a lock for extra precaution.
I used an anonymous method to update the UI thread, but you can abviously do that however you want, as long as you remember to Invoke, it's also a good idea to check the InvokeRequired property
private readonly object chartUpdatingLock = new object();
private void UpdateChartTimerElapsed(object sender, ElapsedEventArgs e)
{
// Try and get a lock, this will cater for the case where two or more events fire
// in quick succession.
if (Monitor.TryEnter(chartUpdatingLock)
{
this.updateChartTimer.Enabled = false;
try
{
// Dequeuing and whatever other work here..
// Invoke the UI thread to update the control
this.myChartControl.Invoke(new MethodInvoker(delegate
{
// Do you UI work here
}));
}
finally
{
this.updateChartTimer.Enabled = true;
Monitor.Exit(chartUpdatingLock);
}
}
}
I've got a queue, which is basically the producer/consumer queue in the albahari.com
threading book, which takes an queue item off the queue, which is an action execution block off the queue and then calls a method to execute the actionlist within the queue item.
I can kill the queue easily enough by enqueing a null actionblock and block the main thread by doing a spin/wait with a thread.sleep() until the queue count goes to zero, and all the threads fall through the while !=null loop, thereby completing, but the method executing the last actionlist may still be executing the last thread.
Question is, is their anyway to detect if that method still has a thread executing it, like maybe using a Semaphore or counter with an Interlock to count the semaphore up at the beginning of the method and count it down at the end. So if it reaches zero, them I know its not threaded.
This is the implementing a destroy method on the interface, to close it down before calling dispose.
Use the Backgroundworker which has a completed event
If you start a thread like this:
System.Threading.Thread mythread = new System.Threading.Thread();
mythread.Start();
You can check:
mythread.IsAlive()
at any point to determine its status.
Use a PostSharp attribute on the method.