9

Is there a synchronous wait function that won't tie up the UI-thread in .NET WPF? Something like:

Sub OnClick(sender As Object, e As MouseEventArgs) Handles button1.Click
     Wait(2000) 
     'Ui still processes other events here
     MessageBox.Show("Is has been 2 seconds since you clicked the button!")
End Sub
1
  • in plain Win32 you can use MsgWaitForMultipleObjects to achieve this. Commented May 24, 2011 at 23:10

2 Answers 2

18

You can use a DispatcherTimer for that sort of thing.

Edit: This might do as well...

private void Wait(double seconds)
{
    var frame = new DispatcherFrame();
    new Thread((ThreadStart)(() =>
        {
            Thread.Sleep(TimeSpan.FromSeconds(seconds));
            frame.Continue = false;
        })).Start();
    Dispatcher.PushFrame(frame);
}

(Dispatcher.PushFrame documentation.)


Starting with .NET 4.5 you can use async event handlers and Task.Delay to get the same behaviour. To simply let the UI update during such a handler return Dispatcher.Yield.

Sign up to request clarification or add additional context in comments.

6 Comments

In WPF you defiantly want to use the DispatcherTimer as it's ticks will execute on the UI's thread enabling you to modify UI controls. If you use a standard timer the ticks execute on its own thread and you will get some nasty exceptions if you try to touch UI controls. +1
Is there anyway to use the timer to do the waits inline. Seems cumbersome and hard to read when you break up a method every time you need a wait.
@PeterM: As i'm not all too well versed in threading issues you might want to take a look at the Threading Model reference and the Dispatcher.PushFrame method, which might help you simplify this.
@PeterM: Actually i think i just got a solution using this method, see my updated answer. (I don't speak VB though...)
|
1

Here is a solution with Task.Delay. I'm using it in unit-tests for ViewModels that use DispatcherTimer.

var frame = new DispatcherFrame();

var t = Task.Run(
    async () => {
        await Task.Delay(TimeSpan.FromSeconds(1.5));
        frame.Continue = false;
    });

Dispatcher.PushFrame(frame);

t.Wait();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.