DispatcherTimer не запускается в приложении wpf

Я недавно реорганизовал свой код 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);

Но ни одна из этих вещей не меняет поведение... оно все равно не срабатывает.

Что я здесь не так делаю?

1 ответ

Решение

DispatcherTime работает на... ветке Dispatcher. Который застрял в ожидании SomeLongRunningTask() заканчивать.

Действительно, когда вы нажимаете кнопку Go, это поток диспетчера, который выполняет GoButton_Click, Таким образом, вы никогда не должны создавать метод, вызываемый пользовательским интерфейсом (поток диспетчера) 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.
}
Другие вопросы по тегам