I've recently started to learn about async-await, and I built a simple app to practice with, now I want to run a for loop, and then in each loop, I want to append the current i
of the loop to my textbox.Text
, and I want it to run asynchronously
I couldn't directly run an async method, because it would complain that the control is being changed by a different thread than the main thread, so I found out that I have to use the BackgroundWorker
class, but in the DoWork
event handler of this BgWorker, I must use thread.sleep()
to make it run asynchronously so my UI remains responsive while the for loop is running, and if I remove the thread.sleep()
, the UI will freeze for a few seconds, and then it writes out the whole thing at once, what if I don't want that thread.sleep()
? why is it required? how is it working? can I make it run asynchronously but without thread.sleep()
?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 1000; i )
{
Thread.Sleep(100); // Why is this required in order to run asynchronously
backgroundWorker1.ReportProgress(i);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
textBox2.Text = e.ProgressPercentage;
}
}
CodePudding user response:
Without the call to Thread.Sleep(100)
, the UI thread can't respond to your input because it's constantly busy updating the UI.
The Worker thread will start and call backgroundWorker1.ReportProgress(i)
immediately. Which will invoke the UI thread to update the textbox and repaint the dialog. When this is done, it will basically immediately call backgroundWorker1.ReportProgress(i)
again and to the exact same thing.
This means that the UI thread, instead of checking for events from user input, is constantly updating the textbox and repainting the dialog.