Reputation: 2799
I have this xaml
<Window x:Class="TestCloseWindow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Width="500" Height="400">
<StackPanel>
<TextBlock x:Name="Seconds"></TextBlock>
<Button Content="fasdfd" Click="ButtonBase_OnClick"></Button>
</StackPanel>
</Window>
And this code
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
await CountToTen();
}
private Task CountToTen()
{
return Task.Factory.StartNew
(() =>
{
for (var i = 1; i <= 10; i++)
{
Seconds.Text = i.ToString(CultureInfo.InvariantCulture);
Task.Delay(1000).Wait();
}
}
, CancellationToken.None
, TaskCreationOptions.None
, TaskScheduler.FromCurrentSynchronizationContext()
);
}
}
In this code I use TaskScheduler.FromCurrentSynchronizationContext() in order to access UI from background Task.
I expected that I can see how program count to ten, but instead of it I see blocked UI for 10 seconds and after 10 in TextBlock
How can I fix it?
Upvotes: 1
Views: 1160
Reputation: 203802
By using StartNew
with TaskScheduler.FromCurrentSynchronizationContext()
, in this particular case, you're not really doing anything at all. Since the entire task will be run in the UI thread it's no different from just executing it right there in line.
The primary source of your problem is Task.Delay(1000).Wait();
. You're doing a blocking wait for a second, and you're doing that from the UI thread. You can refactor the code to not do a blocking wait, and also remove the needless task creation. This is all you need:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
for (var i = 1; i <= 10; i++)
{
Seconds.Text = i.ToString(CultureInfo.InvariantCulture);
await Task.Delay(1000)
}
}
Upvotes: 0
Reputation: 18803
You are using a blocking call Wait
in your CountToTen
function. To fix this you will need to use await
instead. Which requires some other changes as well.
async private Task CountToTen()
{
await Task.Factory.StartNew( async () =>
{
for (var i = 1; i <= 10; i++)
{
Seconds.Text = i.ToString(CultureInfo.InvariantCulture);
//Task.Delay(1000).Wait();
await Task.Delay(1000);
}
}, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
Upvotes: 2