我最近重构了我的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();
    }

(当前类是我的主窗口对象,在文件复制期间我会隐藏它。CopyFilesWindow是一个简单的XAML窗口,它包含我修改的控件…CopyFilesWindow本身什么也不做。)
基本上,我等待一个长时间运行的任务(复制一堆大文件),而我的dispatchertimer应该更新dispatchertimer_tick中的进度。但是,我在那个函数上设置了一个断点,它不会被击中。
我还尝试用构造函数设置dispatcher,如下所示:
        m_dispatcherTimer = new DispatcherTimer(DispatcherPriority.Normal, m_files.Dispatcher);
        m_dispatcherTimer = new DispatcherTimer(DispatcherPriority.Normal, this.Dispatcher);

但这两件事都改变不了我们的行为…它还是不会开火。
我在这里做错什么了?

最佳答案

DispatcherTime运行在…调度线程。它一直在等待完成。
实际上,当您按下按钮SomeLongRunningTask()时,执行Go的是dispatcher线程。因此,您永远不应该创建由ui(dispatcher线程)GoButton_Click调用的方法。

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.
}

09-28 00:02