I have a C# WPF project I want to use a task to display a spinner (loader) without freezing the UI so that the long process is finished.
What I need: I want to show a loading to the user during a heavy operation
What have I done: Well, I have a spinner that is hidden and when heavy operations start, I show that spinner ,But the UI freezes again!
CS:
private void Button1_Click(object sender, RoutedEventArgs e)
{
//Showing the loader
Task.Factory.StartNew(async () =>
{
await Dispatcher.InvokeAsync(() =>
{
Spinner.Visibility = Visibility.Visible;
});
});
//Simulation Long Process
var TheRsult = dbms.Database.SqlQuery<object>("WAITFOR DELAY '00:00:04' SELECT GETDATE()").FirstOrDefault();
Thread.Sleep(500);
for (int i = 0; i < 1000; i )
{
Console.Write(i);
}
}
My Full Source Code : https://filebin.net/n354bf7ngyspoy5f
Please guide me regarding this issue, thank you
CodePudding user response:
You're "Simulation Long Process" on main thread (put a breakpoint at Thread.Sleep(500);
and the IDE will tell you that you're in MainThread)..
You can change your code to something like this
private async void Button1_Click(object sender, RoutedEventArgs e)
{
// Showing the loader
Spinner.Visibility = Visibility.Visible;
// or: await Task.Run(() =>
await Task.Factory.StartNew(() =>
{
// Simulation Long Process
var TheRsult = dbms.Database.SqlQuery<object>("WAITFOR DELAY '00:00:04' SELECT GETDATE()").FirstOrDefault();
Thread.Sleep(500);
for (int i = 0; i < 1000; i )
{
Console.Write(i);
}
});
Spinner.Visibility = Visibility.Hidden;
}
CodePudding user response:
Task
has nothing to do with threading.
And as you can plainly see, there's absolutely nothing running on a separate thread in your code. The first part shows your spinner on your main thread (Dispatcher.InvokeAsync
), and the second part runs straight in the button handler, on the main thread.