为什么内部任务不执行
本文关键字:执行 任务 内部 为什么 | 更新日期: 2023-09-27 18:23:35
在我的wpf应用程序中,我知道我应该更新主线程上的UI元素。我所做的是使用主窗口调度器来做到这一点。我只是好奇为什么这个代码不起作用:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
Console.Write("test");
Task.Factory.StartNew(() =>
{
// why does this code does not execute!! ???
Thread.Sleep(1000);
txt.Text = "Testing";
}, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
});
}
}
为什么内部任务不执行?换句话说,我的程序从未到达Thread.Sleep(1000);
行。为什么是这样?
当调用线程上没有同步上下文(即SynchronizationContext)时,TaskScheduler.FromCurrentSynchronizaContext()可能会抛出InvalidOperationException。Current返回null。
因此,为了捕捉UI TaskScheduler,您应该更早地获得它:
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
{
Console.Write("test");
Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
txt.Text = "Testing";
}, CancellationToken.None, TaskCreationOptions.None, uiScheduler);
});
}
您还可以使用延续任务,并在您需要的线程上运行它:
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
{
Console.Write("test");
}).ContinueWith(() =>
{
Thread.Sleep(1000);
txt.Text = "Testing";
}, CancellationToken.None, TaskCreationOptions.None, uiScheduler);
}
您可以直接使用调度器:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
Console.Write("test");
Thread.Sleep(1000);
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Normal, new Action(() =>
{
txt.Text = "Testing";
}));
});
}
}