I know, it's been here many times, but I still don't know how to do it.
I want to create a program that will repeatedly download data from database, so the user will see the data in the program to this time.
I do not need to load the database quickly, so I use sleep, but sleep freeze whole UI.
I take simple example.
<Window x:Class="ThreadingPrimeNumberSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Prime Numbers" Width="760" Height="500">
<Grid>
<Button Content="Start"
Click="StartOrStop"
x:Name="startStopButton"
Margin="10,10,693,433"
/>
<TextBlock Margin="87,15,547,424"><Run Text="Biggest Prime Found:"/><InlineUIContainer>
</InlineUIContainer></TextBlock>
<TextBlock x:Name="bigPrime" Margin="222,15,409,428"><Run Text="3"/></TextBlock>
<TextBox Height="104" TextWrapping="Wrap" Text="TextBox" Width="522" Margin="87,295,143,70"/>
</Grid>
</Window>
...usings...
namespace ThreadingPrimeNumberSample
{
public partial class MainWindow : Window
{
public delegate void NextPrimeDelegate();
//Current number to check
private long num = 3;
private bool continueCalculating = false;
public MainWindow()
: base()
{
InitializeComponent();
}
private void StartOrStop(object sender, EventArgs e)
{
if (continueCalculating)
{
continueCalculating = false;
startStopButton.Content = "Resume";
}
else
{
continueCalculating = true;
startStopButton.Content = "Stop";
startStopButton.Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
new NextPrimeDelegate(CheckNextNumber));
}
}
public void CheckNextNumber()
{
// Reset flag.
NotAPrime = false;
for (long i = 3; i <= Math.Sqrt(num); i++)
{
if (num % i == 0)
{
// Set not a prime flag to true.
NotAPrime = true;
break;
}
}
// If a prime number.
if (!NotAPrime)
{
bigPrime.Text = num.ToString();
}
num += 2;
Thread.Sleep(500);
if (continueCalculating)
{
startStopButton.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.SystemIdle,
new NextPrimeDelegate(this.CheckNextNumber));
}
}
private bool NotAPrime = false;
}
}
If was process started and I writing to the textbox or doing something... whole is it freezes.
How should this code look to be able to run the process and UI won't be frozen?
To do something periodically, you should use a timer. If you want a timer which fires on the WPF UI thread, use DispatcherTimer
- although the fact that you're downloading data suggests that you should either be doing that asynchronously, or using background threads. For the latter, you could use System.Threading.Timer
.
Basically you should never block the UI thread for significant periods of time, precisely because it will freeze your UI.
See more on this question at Stackoverflow