4

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

但是这些东西都没有改变行为......它仍然没有触发。

我在这里做错了什么?

4

1 回答 1

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.
}
于 2013-07-21T21:59:53.940 回答