Wait Some Seconds Without Blocking UI Execution

Wait for a while without blocking main thread

Thread.Sleep(500) will force the current thread to wait 500ms. It works, but it's not what you want if your entire application is running on one thread.

In that case, you'll want to use a Timer, like so:

using System.Timers;

void Main()
{
Timer t = new Timer();
t.Interval = 500; // In milliseconds
t.AutoReset = false; // Stops it from repeating
t.Elapsed += new ElapsedEventHandler(TimerElapsed);
t.Start();
}

void TimerElapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Hello, world!");
}

You can set AutoReset to true (or not set it at all) if you want the timer to repeat itself.

Waiting for a result before continuing and without blocking UI

This is basically what you want. I'm violating a couple best-practices here, but just showing it's not that complicated. One thing to keep in mind is that the user can now click this button multiple times in a row. You might consider disabling it before processing. Or you can do a Monitor.TryEnter() to make sure it's not already running.

    private async void buttonProcess_Click(object sender, RoutedEventArgs e)
{
textBlockStatus.Text = "Processing...";
bool processed = await Task.Run(() => SlowRunningTask());
}

private bool SlowRunningTask()
{
Thread.Sleep(5000);
return true;
}

Synchronous Wait Without Blocking the UI-Thread

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.

Android sleep() without blocking UI

You can use postDelayed() method like this:

handler=new Handler();
Runnable r=new Runnable() {
public void run() {
//what ever you do here will be done after 3 seconds delay.
}
};
handler.postDelayed(r, 3000);

Adding Delay In A For Loop Without Blocking UI

Would this solution work? Instead of using dispatch_after, I use dispatch_async with a [NSThread sleepForTimeInterval] block, which allows me to put a delay anywhere that I need in my custom queue.

dispatch_queue_t myCustomQueue;
myCustomQueue = dispatch_queue_create("com.example.MyQueue", NULL);

dispatch_async(myCustomQueue, ^ {
NSLog(@“Task1”);
});

dispatch_async(myCustomQueue, ^ {
[NSThread sleepForTimeInterval:2.5];
});

dispatch_async(myCustomQueue, ^ {
NSLog(@“Task2”);
});

dispatch_async(myCustomQueue, ^ {
[NSThread sleepForTimeInterval:3.0];
});

dispatch_async(myCustomQueue, ^ {
NSLog(@“Task3”);
});

dispatch_async(myCustomQueue, ^ {
[NSThread sleepForTimeInterval:2.0];
});

How to wait for thread to complete without blocking UI

I'm very surprised you haven't worked with any of these before but I would really recommend reading about threading in C# since it's fundamentally important to understand the intricacies and learning the language.

Below are three different ways you can achieve what you want:

1. Using reset events (further reading: https://msdn.microsoft.com/en-us/library/system.threading.manualreseteventslim(v=vs.110).aspx). If your C# version doesn't have the ManualResetEventSlim, replace it with ManualResetEvent and change Wait() with WaitOne()

class LockingWithResetEvents
{
private readonly ManualResetEvent _resetEvent = new ManualResetEvent(false);

public void Test()
{
MethodUsingResetEvents();
}

private void MethodUsingResetEvents()
{
ThreadPool.QueueUserWorkItem(_ => DoSomethingLong());
ThreadPool.QueueUserWorkItem(_ => ShowMessageBox());
}

private void DoSomethingLong()
{
Console.WriteLine("Doing somthing.");
Thread.Sleep(1000);
_resetEvent.Set();
}

private void ShowMessageBox()
{
_resetEvent.WaitOne();
Console.WriteLine("Hello world.");
}
}

2) Using Task Parallel Library (TPL). Further reading: https://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx

class LockingWithTPL
{
public void Test()
{
Task.Factory.StartNew(DoSomethingLong).ContinueWith(result => ShowMessageBox());
}

private void DoSomethingLong()
{
Console.WriteLine("Doing somthing.");
Thread.Sleep(1000);
}

private void ShowMessageBox()
{
Console.WriteLine("Hello world.");
}
}

3) Using Async/Await. Further reading: https://msdn.microsoft.com/en-us/library/hh191443.aspx

class LockingWithAwait
{
public void Test()
{
DoSomething();
}

private async void DoSomething()
{
await Task.Run(() => DoSomethingLong());
ShowMessageBox();
}

private async void DoSomethingLong()
{
Console.WriteLine("Doing somthing.");
Thread.Sleep(10000);
}

private void ShowMessageBox()
{
Console.WriteLine("Hello world.");
}
}

Also good to know: Mutex (https://msdn.microsoft.com/en-us/library/system.threading.mutex(v=vs.110).aspx), Semaphore (https://msdn.microsoft.com/en-us/library/system.threading.semaphore(v=vs.110).aspx), Lock (https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx), SemaphoreSlim (https://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim(v=vs.110).aspx), Monitor (https://msdn.microsoft.com/en-us/library/system.threading.monitor(v=vs.110).aspx) and Interlocked (https://msdn.microsoft.com/en-us/library/system.threading.interlocked(v=vs.110).aspx).

C# Need to wait for thread to finish without blocking UI thread

await Task.Run(() => resetEvent.WaitOne()); should do the trick. ManualResetEvent is not awaitable and can't use await keyword directly on it, so you need to wrap it in task

Run a task for two seconds without blocking UI

Yes, I've tried too, but if I do the Task.Delay with async tasc the problem is that normal and reverse mode are tried at the same time. Finally I've made it doing this:

Private Sub autocheck_btStart_Click(sender As Object, e As EventArgs) Handles autocheck_btStart.Click
If Not currentlyTesting Then
currentlyTesting = True
principal.setRecording(True, ecu)
Dim t As Task = Task.Run(Sub()
startTesting()
End Sub)
principal.setRecording(False, ecu)
currentlyTesting = False
End If
End Sub

Public Sub startTesting()
For Each test In tests
tbDebug.AppendText("Testing motor " + test.getName() + Environment.NewLine)
test.executeTest()
Next
showResults()
End Sub

Public Sub executeTest()
isTesting = True
ckNormal.Checked = True
Thread.Sleep(2000)
ckNormal.Checked = False
Thread.Sleep(200)
ckReverse.Checked = True
Thread.Sleep(2000)
ckReverse.Checked = False
Thread.Sleep(200)
isTesting = False
End Sub

Thanks for your advices!!



Related Topics



Leave a reply



Submit