Thread.Sleep() Without Freezing the Ui

Thread.Sleep() without freezing the UI

The simplest way to use sleep without freezing the UI thread is to make your method asynchronous. To make your method asynchronous add the async modifier.

private void someMethod()

to

private async void someMethod()

Now you can use the await operator to perform asynchronous tasks, in your case.

await Task.Delay(milliseconds);

This makes it an asynchronous method and will run asynchronously from your UI thread.

Note that this is only supported in the Microsoft .NET framework 4.5 and higher.

.

Thread.Sleep without freezing UI for Framework 2.0

It seems I was getting this Not Responding on my program, because the other thread I had, that was running constantly, didn't had any Sleep in it, and was running as fast as possible, thus making the program Not Responding and using up to 13% of the CPU...

A simple Thread.Sleep(10); fixed everything

C# Thread.Sleep(ms) Freezes UI and I can't use Alternative Options

Make your click handler async. Then you can use Task.Delay, which will not block the thread.

private async void button_Click(object sender, RoutedEventArgs e)
{
try
{
System.IO.StreamWriter file = new System.IO.StreamWriter(@"New.csv");
int a = 1;
file.WriteLine("Delta, Theta");
while (a < 20)
{
file.WriteLine("{0}, {1}", TGLatestData.EegPowerDelta, TGLatestData.EegPowerTheta);
a++;
file.Close();
await Task.Delay(3000);
}
}
catch (Exception ex)
{
throw new ApplicationException("Broken", ex);
}
}

By the way, here's one way to fix your exception:

private async void button_Click(object sender, RoutedEventArgs e)
{
const string fileName = @"New.csv";
try
{
File.AppendAllText(fileName, "Delta, Theta");
for (var a=1; a<20; a++)
{
var text = string.Format("{0}, {1}", TGLatestData.EegPowerDelta, TGLatestData.EegPowerTheta);
File.AppendAllText(fileName, text);
await Task.Delay(3000);
}
}
catch (Exception ex)
{
throw new ApplicationException("Broken", ex);
}
}

Why does Thread.Sleep() freeze the Form?

To keep the UI active, you need for the main UI thread to service its message pump. It can only do that when it is not handling UI events. In your case the function

private void button1_Click(object sender, EventArgs e)
{
Thread thread1 = new Thread(DoStuff);
thread1.Start();

for (int i = 0; i < 100000; i++)
{
Thread.Sleep(500);
button1.Text +=".";
}
}

does not return for around 100000*500 milliseconds. While this event handler is executing, the UI thread is busy. It is executing this event handler. As such it is not able to service the message pump. Hence your application's UI freezes.

How can I use sleep in while without freezing all app?

With this program you can't! You need to look for options in your programming framework which can do multi threading. Your sleep() function must allow other threads to run.

One nice solution is to invert the logic and use Timers. instead of call sleep to block the operation till the next interaction. Your timer will call your routine many times you want.

Look this: The ultimate guide to Timer

How to make a child thread sleep without freezing UI thread in WPF application?

Have you tried it? Sleeping thread inside a Task won't freeze your GUI but it will make the current background thread to go in sleep mode and your UI will remain responsive always -

        Task.Factory.StartNew(() =>
{
Thread.Sleep(5000000); // this line won't make UI freeze.
});
Thread.Sleep(5000000); // But this will certainly do.

Non freezing sleep in android app

NEVER use Thread.sleep(). If you do, you are blocking the current Thread. That means if you were to call Thread.sleep() on the UI Thread the UI would freeze and you couldn't interact with it anymore, just like you experienced. There are multiple options to schedule some task or event for the future. You can:

  1. Use a Timer
  2. Use a Handler with postDelayed()
  3. Use the AlarmManager

Using a Timer

Timer can be used to schedule a TimerTask. They are best suited to schedule tasks a few seconds to maybe a few minutes into the future.

First you have to write a TimerTask. This task will be executed once the time has elapsed. A TimerTask might look like this:

private class ExampleTask extends TimerTask {

@Override
public void run() {
// This method is called once the time is elapsed
}
}

And you can schedule a TimerTask like this:

Timer timer = new Timer();
ExampleTask task = new ExampleTask();

// Executes the task in 500 milliseconds
timer.schedule(task, 500);

Using a Handler with postDelayed()

Using a Handler is pretty similar to using a Timer, but personally I prefer using a Timer as they are just better suited for jobs like this. Handler were originally meant to facilitate communication between Threads and other things, but they can also be used to scheduling a Runnable. First we have to define a Runnable, this is pretty similar to the TimerTask:

Runnable runnable = new Runnable() {

@Override
public void run() {
// This method will be executed in the future
}
};

And now we schedule the Runnable to be executed in the future with postDelayed():

Handler handler = new Handler();

// Execute the Runnable in 500 milliseconds
handler.postDelayed(runnable, 500);

Using the AlarmManager

The AlarmManager is a system service and can be used to send an Intent at some point in the future. You can schedule this Intent for months or even years into the future with the AlarmManager, the only drawback is that you have to reset all alarms when the phone is rebooted.

You can get the AlarmManager like this:

AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

You also need to wrap the Intent you want to send in a PendingIntent:

Intent intent = new Intent(SOME_ACTION);
... // Setup your intent
PendingIntent pendingIntent = PendingIntent.getService(context, REQUEST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT);

And you can schedule the Intent to be sent at a specific Date like this:

manager.set(AlarmManager.RTC, date.getTime(), pendingIntent);


Related Topics



Leave a reply



Submit