Wpf UI doesnt update if I use Thread.Sleep - wpf

private void Window_ContentRendered_1(object sender, EventArgs e)
{
StatusLabel.Text = "Doesnt show up until the sleep is over...0_0";
System.Threading.Thread.Sleep(2000);
}
I want to ask why does it heppend and only then a solution. thanks all

Issue is you are sleeping on UI thread.
After first line execution you slept on UI thread but it's UI thread responsibility to refresh UI (UI thread refreshes UI on Render dispatcher priority). Hence, you see no update after first line execution because UI thread never gets time to execute render priority items queued on dispatcher.
Ideally, you should use DispatcherTimer to wait on UI thread for certain interval of time and then update once interval time is elapsed.
Also, either you should move the long running task on background thread using backgroundWorker and sleep on that thread instead on UI thread. Also as SLaks suggested you can use async/await to get desired result.
However, quick and dirty solution would be to dispatch empty delegate on UI thread with Dispatcher priority set to Render just before you slept on it so that UI refresh part gets executed before thread falls in sleep state.
StatusLabel.Text = "Doesnt show up until the sleep is over...0_0";
lbStatus.Dispatcher.Invoke((Action)(() => { }), DispatcherPriority.Render);
Thread.Sleep(2000);
Idea here is once you queue empty delegate on UI dispatcher with render priority, it will execute all pending items with priority higher or equal to Render. Since, UI refresh is done on on Render priority, UI will be refreshed and you will see update in label content on GUI.

Related

Run a callback after mouse scrolling is done in C with Gtk

I'm working on a C application using Gtk for the GUI. We have custom slider widgets connected to the "mouse scrolled" event with a callback function. The problem is each scrolling increment will trigger the callback once, which updates a parameter and refreshes a computationaly-expensive rendering. So, when the user scrolls more than once, the GUI freezes until all scrolls are processed individually in sequence.
I want to have the multiple unit scrolling increments recorded as one flat increment, such that the expensive rendering is started only once the user is done scrolling, so we only record all increments until the scrolling is finished and then we update the parameter and refresh the rendering.
My first idea was to have the "mouse scrolled" callback emit some "update" signal and save :
the timestamp of the scroll event long t,
the number of scrolling increments int steps
Each new scrolling event would increment the steps counter and overwrite the timestamp.
Then, the "update" signal would be captured by a function that would wait for t + 0.5 s to actually save the slider value and trigger a new rendering. If the user performs a new scrolling during that time, the function would just keep waiting.
Is there a Gtk or C API to perform that kind of task ?

Strange behaviour Bindings with plain Properties with Property Changed and Busy UIThread

I have a property like this.
public double RollDegrees
{
get
{
return rollDegrees;
}
set
{
if (rollDegrees != value)
{
rollDegrees = value;
OnPropertyChanged(PROPERTY_NAME_ROLL_DEGREES);
}
}
It is binding to a xaml control and the UI updates perfect in normal conditions.
This property is updated on NON-UI Thread but as far I know it not neccesary to put the update on a Dispatcher.BeginInvoke with plain properties.
But when the app is running a busy update on the UI thread (map control moving fast with updates) The UI Binding of this property is not updated, then when the busy update finish the property again updates the UI.
But if I put
Application.Current.Dispatcher.BeginInvoke((Action)(() =>
{
RollDegrees = (OperationEntity as Level).RollDegrees;
}));
Then the UI works perfect
Any hints of why this is happening?? Maybe something in the busy update?? Or this is a normal behaviour when the UI Dispatcher is full and busy??
All UI elements should be updated only in UI thread. Each thread has it's own dispatcher. In case if you need update UI from non-UI thread, you should call Application.Current.Dispatcher.BeginInvoke(). Hence it is normal behavior.
In the first scenario, you're updating the property, but not from the UI thread. Hence the delay caused till the UI thread comes into action. When you're using the Application.Current.Dispatcher.BeginInvoke(), the UI is updated immediately.
So if you want to reflect some changes related to UI from a different thread, use Application.Current.Dispatcher.BeginInvoke().
Read more # https://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.begininvoke(v=vs.110).aspx

WPF Ensure RenderTargetBitmap has updated Binding values from background thread changes

I'm having a problem with RenderTargetBitmap, in that I can't get it consistently grab an updated render after I change bound properties on a background thread.
Here is what I have:
// Update a property on an INotifyPropertyChanged view model
// This runs on a background thread
viewModel.SomeBoundProperty += 10;
// Flush dispatcher queue (from http://stackoverflow.com/a/2596035/612510)
_lcd.Dispatcher.Invoke(() => {}, System.Windows.Threading.DispatcherPriority.Loaded);
// Render the updated control
_lcd.Dispatcher.Invoke(() =>
{
_lcd.Measure(new System.Windows.Size(240, 160));
_lcd.Arrange(new System.Windows.Rect(0, 0, 240, 160));
_lcd.UpdateLayout();
_renderTarget.Render(_lcd);
}
Alas, approximately half the time I'm getting the render before the control is updated with the new value, and the other half it updates correctly.
From what I understand WPF dispatches property change notifications automatically to the UI thread. How can I ensure that these dispatched notifications are all processed before doing the render? This code works fine if I make sure SomeBoundProperty is updated on the Dispatcher thread, but that is less than ideal for this particular application.
Any suggestions?
Some trial and error has me figuring that property change notifications are dispatched at the DispatcherPriority.Background priority, so changing the flushing line to this:
// Flush dispatcher queue
_lcd.Dispatcher.Invoke(() => {}, System.Windows.Threading.DispatcherPriority.ContextIdle);
...looks like it fixed the problem. DispatcherPriority.ContextIdle is one level below DispatcherPriority.Backgound. The render now updates consistently every time.

Silverlight fire an event then fire another even a second later

Is there a way to do something like this?
Background:
I have a button click. When the button is clicked I try to show a "loading" message, run a bunch of code that does some UI work and then dismiss the "loading" message. It takes anywhere from a few seconds to 20 seconds usually. At the moment the loading message doesn't show at all and the UI freezes until the code in my button click is done.
I've read about Background Worker and dispatcher, but haven't been able to get it to work. I'm not sure if it's because the code in the button click calls all sorts of other code (including 3rd party stuff), but I haven't been able to get it to run correctly. It all still works, but it still freezes the UI and the loading message doesn't appear.
So, I am wondering if there is another way around this. Is it possible to set it up so that on the button click I only show the loading message and then a second or so later fire another event that executes my long running process? That way the UI will still freeze for some seconds, but at least it will show a "loading" message.
You should be able to do this with a Dispatcher.BeginInvoke call.
private void ButtonClick(object sender, EventArgs e)
{
ShowMyLoadingMessage(); // your code, not sure what it is
Dispatcher.BeginInvoke(() =>
{
CallMyLongRunningCode(); // again, not sure what this is
HideMyLoadingMessage();
}
}
I don't believe this is the best solution since it is running on the UI thread, but it should do what you are asking.
What is the long running code doing that takes 20 seconds?

WPF updating the UI with a certain delay

I have a slideshow application where i want to wait a certain amount of seconds, then show my front page, then wait again, then show next page, and so on. My problem is that when i use Thread.Sleep in between, the UI arent updated, it just sits there waiting and i only see my last control (after the full amount of time has passed (i.e all the sleeps). Any solutions for doing this?
Thread.Sleep(1000);
ChangeContent(new FrontPage());
Thread.Sleep(5000);
ChangeContent(new HtmlPage());
Pre WPF i would just use the Application.DoEvents.
Use a DispatcherTimer.

Resources