我有这个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>
这段代码
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()
);
}
}
在此代码中,我使用TaskScheduler.FromCurrentSynchronizationContext()来从后台任务访问UI。
我希望我能看到程序计数到十,但不是它,我看到阻止的UI 10秒和TextBlock中的10后
我该如何解决?
答案 0 :(得分:2)
您在Wait
功能中使用了阻止来电CountToTen
。要解决此问题,您需要使用await
。这也需要一些其他的改变。
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());
}
答案 1 :(得分:0)
将StartNew
与TaskScheduler.FromCurrentSynchronizationContext()
一起使用,在这种特殊情况下,您根本就没有做任何事情。由于整个任务将在UI线程中运行,因此它与在线执行它没有什么不同。
问题的主要来源是Task.Delay(1000).Wait();
。您正在进行阻塞等待一秒钟,而您正在从UI线程进行。您可以重构代码以不执行阻塞等待,还可以删除不必要的任务创建。这就是你所需要的:
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)
}
}