Reputation: 683
I've wrote this simple program to wait for 2sec and then update a textbox:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 10; i++)
{
doSomething(i);
}
}
public void doSomething(int i)
{
System.Threading.Thread.Sleep(2000);
textBox1.Text += "this is the " + i + "th line\n";
}
}
}
but when I run it, the UI pauses and I cannot do anything with UI. it isn't dynamic and all the text which must be shown on textbox1 are shown at the end of running.
is there any alternative instead of System.Threading.Thread.Sleep?
Upvotes: 2
Views: 1975
Reputation: 81253
Issue is you are sleeping on UI thread. Hence UI won't update until you are sleeping on it.
In your case ideal scenario would be to use DispatcherTimer instead of sleeping on UI thread.
private void button1_Click(object sender, RoutedEventArgs args)
{
int i = 0;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(2);
timer.Tick += (s, e) =>
{
if (i == 10)
{
timer.Stop();
}
else
{
textBox1.Text += "this is the " + i + "th line\n";
++i;
}
};
timer.Start();
}
Note - I am suggesting DispatcherTimer here instead of Timer class because Timer executes its Elapsed event handler on background thread so for UI to update you have to delegate the code on UI dispatcher. But DispatcherTimer executes Tick event handler on UI thread itself so no need to marshal things back on UI dispatcher.
Upvotes: 4
Reputation: 3660
The simple way:
private void button1_Click(object sender, RoutedEventArgs e)
{
DoSomethingAsync();
}
private async void DoSomethingAsync()
{
for (int i = 0; i < 10; i++)
{
await doSomething(i);
}
}
async Task doSomething(int i)
{
await Task.Delay(1000);
textBox1.Text += "this is the " + i + "th line\n";
}
Upvotes: 1
Reputation: 15364
You can use async/await without blocking the UI thread.
for (int i = 0; i < 10; i++)
{
await doSomething(i);
}
public async Task doSomething(int i)
{
await Task.Delay(2000);
this.Text += "this is the " + i + "th line\n";
}
Upvotes: 5