Правильно отмените асинхронную операцию и запустите ее снова

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

Моя идея состояла в том, чтобы сначала проверить, работает ли асинхронная операция, отменить ее и запустить снова.

До сих пор я пытался создать такую функциональность, используя CancellationTokenSource, но она не работает должным образом. Иногда выполняется две асинхронные операции, поэтомустарый» Асинхронные операции еще не отменены, когда я запускаю новую, и это смешивает обработку результатов.

Какие-нибудь предложения или примеры, как обращаться с этим случаем?

public async void Draw()
{
    bool result = false;

    if (this.cts == null)
    {
        this.cts = new CancellationTokenSource();

        try
        {
            result = await this.DrawContent(this.TimePeriod, this.cts.Token);
        }
        catch (Exception ex)
        {}
        finally
        {
            this.cts = null;
        }
    }

    else
    {
        this.cts.Cancel();
        this.cts = new CancellationTokenSource();

        try
        {
            result = await this.DrawContent(this.TimePeriod, this.cts.Token);
        }
        catch (Exception ex)
        {}
        finally
        {
            this.cts = null;
        }
    }

}

РЕДАКТИРОВАТЬ: В конце концов, я думаю, это не плохо, что за короткое время выполняются две асинхронные операции (когда запускается новая, но старая еще не отменена).

Реальная проблема здесь в том, как я показываю прогресс для конечного пользователя. Когда старая асинхронная операция завершается, она скрывает индикатор выполнения от конечного пользователя, но вновь запущенная асинхронная операция все еще выполняется.

РЕДАКТИРОВАТЬ 2: Внутри DrawContent (...) Я использую ThrowIfCancellationRequested, поэтому отмена выполнения задачи, кажется, работает нормально.

О показе прогресса. Когда вызывается Draw (), я устанавливаю индикатор загрузки видимым, а когда этот метод заканчивается, я скрываю индикатор загрузки. Так что теперь, когда предыдущая асинхронная операция отменяется после запуска новой, мой индикатор загрузки становится скрытым. Как я должен отслеживать, если есть еще один асинхронный метод все еще работает, когда "старый» один заканчивается.

Ответы на вопрос(3)

Ваш ответ на вопрос