When making UI updates with GTK# (GDK2), such as changing label text, setting button visibility etc, should I as a general rule be using Gdk.Threads.AddTimeout or Gdk.Threads.AddIdle?
The GDK2 documentation states that AddIdle
Adds a function to be called whenever there are no higher priority events pending.
So it would seem that AddTimeout would provide a more responsive update. However the documentation states:
Note that timeout functions may be delayed, due to the processing of
other event sources. Thus they should not be relied on for precise
timing.
Which leads me to believe Idle and Timeout are both about as responsive as each other (which they seem to be, when running code).
A comment in some code I am working on suggests that Timeout results in a faster update but hits the UI harder, but I cannot find any sources to back this up.
So as a general rule, which of these methods should I be using to perform GTK updates in the main thread?
Threads.AddTimeout(0, 0, () =>
{
// do something;
return false;
});
vs
Threads.AddIdle(0, () =>
{
// do something;
return false;
});
The timeout callback is appropriate if you need something to happen after a specific period of time. An example of this would be blinking a cursor in a text field (not that you should implement that yourself).
Idle timeout gets called the once the main loop finishes executing everything else that is ready. The difference if you are just calling it once is priority. If you have some other event being handled by the main loop doing it in the idle handler guarantees that the other thing happens first.
The difference becomes more readily apparent when you return true, and get a repeated callback. If you do this in an idle callback you end up using as much CPU as the OS will let you, but your UI remains responsive assuming each callback is fast. If you do this with a timeout you get much more predictable behavior.
The only reason I would think this hits the UI harder is that it defaults to a higher priority, and could potentially delay draw events. Priority DEFAULT_IDLE < HIGH_IDLE (draw) < DEFAULT.
Related
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 are using Task in our application. In one class we want to trigger an update that is running on a parallel task. The call looks like:
Maintenance.RecievedMessage += new NotificationHandler(Maintenance_RecievedMessage);
Maintenance.checkLastXML = false;
Maintenance.NeedToUpdateFromCarrier(userId);
SpinWait.SpinUntil(() => isCompleted == true);
return true;
So we hook up an event that is triggered when the Maintenance.NeedToUpdateFromCarrier(userId);
method is done running. The complete method looks like:
private void Maintenance_RecievedMessage(IsCompleted changeargs)
{
isCompleted = true;
}
So we are waiting for the NeedToUpdateFromCarrier method, as soon as it's done it triggers the event that its done, and we catch the event and set the property isComplete to true, and thats when the SpinWait.SpinUntil finnaly is done, and we continue.
Since SpinWait.SpinUntil is very heavy for the CPU, I'm now looking for an alternative solution to this problem.
It is important to understand when spin-waiting is appropriate. There are very few cases where it is. Spin-waiting optimizes thread context switching. Whenever you wait for something, a call like WaitHandle.Wait() will block the thread and yield the processor. The operating system performs a thread context switch when it finds some other thread to perform useful work.
Thread context switches are pretty expensive. There's no exact number because it depends on where the yield-to thread runs, there's extra overhead when that thread runs in another process or protection ring (drivers). It costs between 2000 and 10,000 cycles.
Those are cpu cycles that don't accomplish much. Just overhead that doesn't get real work done. You can optimize your threading code if you know that it always takes less than 20,000 cycles for the wait condition to be met. Just delaying your thread (spinning) will then ensure that the expensive context switching isn't needed. This is not the normal kind of delay like Thread.Sleep(), that yields, it is small loop that burns 100% core. With a few smarts thrown in, like spinning on a machine with only one core will never work well so it yields anyway.
Clearly this will not work well if the wait condition consistently takes more than 20,000 cycles. Now you're on the other end of the wise choice, you do want to yield in those cases. Not just to avoid burning cpu when it doesn't accomplish anything but especially so because yielding makes it now more likely that the wait condition will be met sooner. Because you increase the odds that the thread that sets the wait condition can get enough cpu cycles to finish its job.
There's plenty of evidence that's the case in your code. You explicitly ask code to do something before spinning. And it requires an event handler to signal the completion. Mucho code needs to run. And most convincingly, you are seeing lots of cpu being burned. 1% of load in TaskMgr.exe is about 20 million cpu cycles.
Use a waitable event instead, like AutoResetEvent. Note the structural change required, isCompleted can't be a bool anymore. You call Set() in the completion handler, Wait() to block on it.
You can use a ManualResetEventSlim:
var signal = new ManualResetEventSlim();
Maintenance.RecievedMessage += delegate { signal.Set(); };
Maintenance.checkLastXML = false;
Maintenance.NeedToUpdateFromCarrier(userId);
signal.Wait();
return true;
We're using WebClient DownloadDataCompleted & DownloadProgressChanged events. We noticed that the progress event can fire an indeterminate number of times and not return from each callback, and still the DataCompleted event will fire. The reason DownloadProgressEvent doesn't return is because it's updating the ProgressBar on the form, which is going through a Control.Invoke cycle. We don't use BeginInvoke for other reasons (ProgressBar max and min change constantly and this cause assertions, since we can't sync up progress updates with progress bar max/min settings).
The question is: Whats the best approach for this?
Simply put, we don't want to acknowledge a completed download until the ProgressBar finishes updating. This implies something of a reverse semaphore that counts up, and is set when it goes back down to zero. We could just use a counter to increment/decrement when entering/leaving DownloadProgress callback, but I would have thought there's something more OS specific.
I would go for the following:
DownloadDataCompleted += delegate {
progressBar.Invoke(() => {
progressBar.Value = progressBar.Maximum;
progressFinished = true;
}
};
DownloadProgressChanged += delegate {
progressBar.Invoke(() => {
if (!progressFinished)
progressBar.Value =
progressBar.Minimum +
(progressBar.Maximum - progressBar.Minimum) * progressRatio;
}
};
There should be no problems with changing the Maximum and Minimum, since all the changes occur anyway in the UI thread.
(The code which changes Maximum or Minimum must take care about recalculating the Value, of course.)
P.S.: Edited the post, taking #Ben Voigt's suggestion into account.
I would be inclined to use BeginInvoke to handle the control update, but arrange for the an atomic update of fields holding the requested "current" and "maximum" values, along with a flag that indicates an update has been requested. The UI's update routine should not hold any locks while performing the update. If locks are used, the UI should grab the lock, make a local copy of the values (including the flag), clear the flag, release the lock, and redraw if necessary. The routine (on the other thread) which wants to request the update should grab the lock, update the values, and--if the flag isn't already set--set the flag and perform a BeginInvoke.
That will ensure that no matter how often the non-UI thread requests an update, at most one BeginInvoke will be outstanding. Further, every update will have usable values for "current" and "maximum".
How do you implement busy waiting in a not total inefficient way? I am facing the issue that I can load the data of my model only in a pull manner, which means I have to invoke getXYZ() methods in a continuous way.
This has to happen not fast enough for user interaction, but fast enought, that when a state in the GUI is changed, the model can be noticed and the new state is received by the getXYZ() methods.
My approach simply be:
while (c.hasChanged()) {
Thread.sleep(500);
}
updateData();
Are there better mechanisms?
Your problem seems to be solvable with Threading.
In WPF you can do:
Thread t = new Thread((ThreadStart)delegate() {
while (true) {
Thread.sleep(500);
if (c.hasChanged())
Dispatcher.Invoke((Action)delegate() {updateData();});
}
}).Start();
In WinForms
Thread t = new Thread((ThreadStart)delegate() {
while (true) {
Thread.sleep(500);
// this must derive from Control
if (c.hasChanged())
this.Invoke((Action)delegate() {updateData();});
}
}).Start();
There may be missing parameters to Invoke (which is needed to execute the code on the calling UI thread) but I'm writing this from my brain so no intellisense at disposal :D
In .NET 4 you can use TaskFactory.StartNew instead of spawning a thread by yourself.
In .Net <= 4, you could use the TreadPool for the thread.
However I recall you need this to be run at once because you expect it to be there checking as soon as possible and the thread pool won't assure you that (it could be already full, but not very likely:-).
Just don't do silly things like spawning more of them in a loop!
And inside the thread you should put a check like
while (!Closing)
so that the thread can finish when you need it without having to resort to bad things like t.Abort();
An when exiting put the Closing to true and do a t.Join() to close the checker thread.
EDIT:
I forgot to say that the Closing should be a bool property or a VOLATILE boolean, not a simple boolean, because you won't be ensured that the thread could ever finish (well it would in case you are closing the application, but it is good practice to make them finish by your will). the volatile keyword is intended to prevent the (pseudo)compiler from applying any optimizations on the code that assume values of variables cannot change
It's not clear from your post exactly what you are trying to do, but it sounds like you should put your model/service calls on a separate thread (via Background worker or async delegate) and use a callback from the model/service call to notify the UI when it's done. Your UI thread can then do busy things, like show a progress bar, but not become unresponsive.
If you are polling from a GUI, use a (WinForms) Timer.
If this is some kind of background process, your Sleep() may be the lesser evil.
Explicit busy waiting is evil and must be avoided whenever possible.
If you cannot avoid it, then build your application using the Observer design pattern and register the interested objects to an object which performs the polling, backed by a thread.
That way you have a clean design, confining the ugly stuff in just one place.
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);
}
}
}