Утилизация таймера, который применяет изменения в потоке пользовательского интерфейса при закрытии приложения WPF - PullRequest
0 голосов
/ 14 мая 2018

Рассмотрим таймер, который будет срабатывать при событии Clicked в приложении WPF, например:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    Timer t = new Timer(DoingWorkOnUI,null,0,5000);

    //Also doing long execution time job here. in another thread
}

В основном проблема заключается в том, что, если пользователь закрывает приложение, мой таймер все еще работает и никогда не выставляетсяв результате задача была отменена ошибка.Я хотел бы убрать это в его обратном вызове, но я не могу понять, как я это сделаю.

Вот моя попытка, я могу ошибаться, но я могу хорошо отменить отмену, я просто не могу найти решение о том, как избавиться от таймера.

private void DoingWorkOnUI(object state) {
    cts = new CancellationTokenSource();
    var token = cts.Token;
    try
    {
        token.ThrowIfCancellationRequested();
        this.Dispatcher.Invoke((Action)(() =>
        {
            \\Doing work on UI
        }));
    }
    catch (OperationCanceledException)
    {
        //Dispose Timer here ???
    }
    finally {
        //Disposing token
        cts.Dispose();
    }
}

1 Ответ

0 голосов
/ 15 мая 2018

Вы можете обработать событие Closing окна для удаления таймера.

Поскольку вы создаете поле IDisposable в своем классе, вы также должны реализовать шаблон dispose , чтобы соответствовать рекомендациям передового опыта:

public partial class MainWindow : Window, IDisposable
{
    private Timer _t;

    public MainWindow()
    {
        Closing += OnClosing;
    }

    private void OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        Dispose(true);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if(_t != null)
            _t.Dispose();

        _t = new Timer(DoingWork, null, 0, 5000);
    }

    private void DoingWork(object state)
    {
        //....
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing && _t != null)
            _t.Dispose();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...