Program Freezes During Thread.Sleep() and with Timer

Program freezes during Thread.sleep() and with Timer

Never use Thread.sleep() when code is executing on the Event Dispatch Thread.

Instead you should use a Swing Timer to schedule your animation.

See the sections from the Swing tutorial on:

  1. Concurrency in Swing
  2. How to Use Timers

Or if you don't want to use a Timer, then you can use a SwingWorker (as described in the tutorial on concurrency) and then just publish() the image after you change it. Then you can use a Thread.sleep() since the SwingWorker doesn't execute on the EDT.

Simple Timer example:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;

public class TimerTime extends JPanel implements ActionListener
{
private JLabel timeLabel;
private int count = 0;

public TimerTime()
{
timeLabel = new JLabel( new Date().toString() );
add( timeLabel );

Timer timer = new Timer(1000, this);
timer.setInitialDelay(1);
timer.start();
}

@Override
public void actionPerformed(ActionEvent e)
{
// Update the time

timeLabel.setText( new Date().toString() );
count++;

// Stop after 10 events have been generated

if (count == 10)
{
Timer timer = (Timer)e.getSource();
timer.stop();
System.out.println( "Timer stopped" );
}
}

private static void createAndShowGUI()
{
JFrame frame = new JFrame("TimerTime");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TimerTime() );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}

public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
}
}

System.Threading.Thread.Sleep() freezes my code when clicking on a line

The problem is that your sleep code is running on the "Main Thread" of your application. This means that your application can't really do anything else while it's in the .slowly() method.

You need to do something like what @vidstige shows, which is to have your .slowly() method run in another (helper) thread.

A more modern approach would be to:

        static async Task slowly(string sen)
{
await Task.Run(() =>
{
for (int j = 0; j < sen.Length - 1; j++)
{
Console.Write(sen[j]);
System.Threading.Thread.Sleep(100);
}
Console.WriteLine(sen[sen.Length - 1]);
System.Threading.Thread.Sleep(100);
});
}

public static void Main(string[] args)
{

var slowlyTask = slowly("hello world");

//do stuff while writing to the screen
var i = 0;
i++;

//wait for text to finish writing before doing somethign else
slowlyTask.Wait();

//do another something after it's done;
var newSlowlyTask = slowly("goodbye");
newSlowlyTask.Wait();
}

PS: The amount of negative responses to this question is disappointing :(

How to delay an answer while not freezing the thread?

Consider using a Timer to prevent main thread from freezing :

import javax.swing.*;
import java.awt.event.*;

ActionListener task = new ActionListener() {
public void actionPerformed(ActionEvent evt) {

}
};
Timer countdown = new Timer(1000 ,task);
countdown.setRepeats(false);
countdown.start();

where 1000 is the delay time in milliseconds and inside the actionPerformed function is where your code executes after the delay time set.

Thread.Sleep() is freezing

Don't ever call Thread.sleep(...) from within the Swing event thread as this will put the event thread itself to sleep. Since this thread is responsible for all Swing painting and user interaction, this will put your application to sleep.

If all you want is a delay in the display, then consider use of a Swing Timer.

If on the other hand your event thread is being compromised by a long-running task, then do the task in the background, using a SwingWorker (as suggested by Guillaume 1+ to him).

Thread.sleep not crashes my app

Thread.sleep(miliseconds) "causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds"

means,

If you are calling Thread.sleep() on MainThread i.e UI thread, It will freeze the UI and causes the thread to definitely stop executing for a given amount of time; So if there is no other thread needs to be run, CPU will goes in Idle mode. I think It won't create ANR.

ANR situation will happen if some large operation is going to operate on UI thread. Consider this example of calculation..

If you are clicking on Button and perform a code like -

public void onClick(View v) {
....
int a = 1;
while(true) {
a++;
}
}

This will cause an ANR.

Here is some reference about ANR -

  • ANR (Force close/Wait) while generating a big enough list
  • Forcing ANR for testing purpose

Check out this documentation How to avoid ANR

Thread.Sleep freeze the UI

I have it:

newtheard(); // This start new theard with loading form database   

public void newtheard()
{
Thread thread = new Thread(new ThreadStart(this.ReadFromMysql);
thread.IsBackground = true;
thread.Name = "My Worker.";
thread.Start();
}

public void ReadFromMysql()
{
while (true)
{
Thread.Sleep(800);
try
{
// some mysql reader
}
}

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.



Related Topics



Leave a reply



Submit