我最近重构了我的WPF代码,现在我的DispatcherTimer停止了解雇。我在这里检查了其他类似的帖子,但是他们似乎都遇到了错误的调度程序线程设置问题,我试过...
我的代码如下所示:
class MainWindow : Window
{
private async void GoButton_Click(object sender, RoutedEventArgs e)
{
Hide();
m_files = new CopyFilesWindow();
m_files.Show();
m_dispatcherTimer = new DispatcherTimer();
m_dispatcherTimer.Tick += dispatcherTimer_Tick;
m_dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 250);
m_dispatcherTimer.Start();
await SomeLongRunningTask();
m_files.Hide();
Show();
}
(当前类是我的主要Window对象,我在文件复制期间隐藏它.CopyFilesWindow是一个简单的Xaml窗口,其中包含我修改的控件... CopyFilesWindow本身绝对没有。)
基本上,我等待一个长时间运行的任务(复制一堆大文件),我的DispatcherTimer应该更新dispatcherTimer_Tick中的进度。但是,我在该函数上设置了一个断点,它没有被击中。
我也尝试使用类似的构造函数设置Dispatcher:
m_dispatcherTimer = new DispatcherTimer(DispatcherPriority.Normal, m_files.Dispatcher);
m_dispatcherTimer = new DispatcherTimer(DispatcherPriority.Normal, this.Dispatcher);
但这些都不会改变这种行为......它仍然没有发射。
我在这里做错了什么?
答案 0 :(得分:5)
DispatcherTime
在... Dispatcher线程上运行。哪个等待SomeLongRunningTask()
完成。
实际上,当您按下按钮Go
时,它是执行GoButton_Click
的调度程序线程。因此,您永远不应该创建UI调用的方法(调度程序线程)async
。
private void GoButton_Click(object sender, RoutedEventArgs e)
{
Hide();
m_files = new CopyFilesWindow();
m_files.Show();
m_dispatcherTimer = new DispatcherTimer();
m_dispatcherTimer.Tick += dispatcherTimer_Tick;
m_dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 250);
m_dispatcherTimer.Start();
SomeLongRunningTask.ContinueWith(() =>
{
// Executes this once SomeLongRunningTask is done (even if it raised an exception)
m_files.Hide();
Show();
}, TaskScheduler.FromCurrentSynchronizationContext()); // This paramater is used to specify to run the lambda expression on the UI thread.
}