Отменить задачу в С#

Я все еще учусь программировать и делаю новый проект с формами MDI (C# и Visual Studio 2019). В mdichild запустил задачу, но если форма выгружается, задача все равно остается. Я хотел бы знать, как отменить задачу даже при нажатии кнопки отмены.

Код:

private async void BuscaActualizaciones()
{
    await Task.Run(() => DoLongThing());
}

private void DoLongThing()
{
    //some hard stuff
}

private void BtnBuscar_Click(object sender, EventArgs e)
{
    //In here i launch the task with hard stuff
    BuscaActualizaciones();
}

Этот код работает отлично, но мне нужно отменить некоторые события, и я не знаю, как это сделать.

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

Правильный способ сделать это — передать CancellationToken и отреагировать на него внутри задачи.

freakish 02.12.2022 11:12

Я удалил тег Visual Studio 2019, потому что этот вопрос не об использовании Visual Studio, поэтому он не имеет значения.

ProgrammingLlama 02.12.2022 11:13

Во-первых, вам нужно, чтобы это было private async void BtnBuscar_Click(object sender, EventArgs e) и await BuscaActualizaciones(), которое должно быть private async Task BuscaActualizaciones(). Тогда можно смотреть дальше...

Fildor 02.12.2022 11:15

Итак, вы хотите отменить DoLongThing без сотрудничества? Вы хотите, так сказать, «убить» его в произвольном месте во время выполнения?

Theodor Zoulias 02.12.2022 12:35
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
196
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Как отметил @freakish в комментарии, правильный способ сделать это — использовать CancellationToken. Вот простой пример, если у вас есть кнопка, которая отменяет задачу при нажатии:

CancellationTokenSource cts = new();

private async Task BuscaActualizaciones()
{
    await Task.Run(DoLongThing, cts.Token); 
}

private Task DoLongThing() // <-- needs to return a Task
{
    //some hard stuff
    cts.Token.ThrowIfCancellationRequested();
    //some hard stuff
}

private void CancelButton_Click(object sender, EventArgs e)
{
    cts.Cancel();  // <-- here is the cancallation
}

Также настоятельно рекомендую документацию по "Асинхронное программирование с помощью async и await".

Пожалуйста, исправьте private async void BuscaActualizaciones()? ... ОП все еще учится.

Fildor 02.12.2022 11:24

а как конкретно?

Dav3 02.12.2022 11:32

Вы продолжаете использовать этот токен отмены... 😃 Экскурсия по задаче, часть 9: делегирование задач Стивена Клири.

Theodor Zoulias 02.12.2022 12:33

Это не отменит выполнение метода DoLongThing. Цитата из документации Task.Run: Токен отмены позволяет отменить работу, если она еще не началась.

Alexander Petrov 02.12.2022 13:02
CancellationTokenSource cts = new CancellationTokenSource ();

private async void BuscaActualizaciones()
{
    await Task.Run(() => DoLongThing(), cts.Token); 
}

private Void DoLongThing() 
{
    //some hard stuff

       if (cts.IsCancellationRequested)
              {
                 throw new TaskCanceledException();
              }
}

private void CancelButton_Click(object sender, EventArgs e)
{
    cts.Cancel();  // <-- here is the cancellation
}

Это работает отлично. спасибо всем за помощь. cts.IsCancellationRequested я прочитал в гугле. Спасибо .

async void -- работает отлично.
Blindy 02.12.2022 16:49

Я не знаю, почему отрицательный голос....

Dav3 03.12.2022 10:28
Ответ принят как подходящий

Как указывали другие, в правильном решении будет использоваться CancellationToken. Однако вы не хотите передавать его Task.Run; вы хотите передать его DoLongThing, как таковой:

CancellationTokenSource cts = new ();

private async void BuscaActualizaciones()
{
  await Task.Run(() => DoLongThing(cts.Token)); 
}

private void DoLongThing(CancellationToken token)
{
  ...
  token.ThrowIfCancellationRequested();
}

private void CancelButton_Click(object sender, EventArgs e)
{
  cts.Cancel();
}

Опрос на отмену (ThrowIfCancellationRequested) распространен для методов, привязанных к ЦП, которым необходимо периодически проверять, отменены ли они. У меня есть запись в блоге , в которой более подробно рассказывается на эту тему .

Спасибо, Стивен. Один вопрос .. где я должен распоряжаться cts?

Dav3 03.12.2022 11:10

Поскольку это переменная уровня класса, сделайте класс одноразовым и удаляйте cts при удалении класса.

Stephen Cleary 03.12.2022 13:51

Спасибо Степану за помощь. Последний вопрос: если DoLongThing (токен CancellationToken) возвращает, например, список объектов или целое число, как я могу получить это значение из BuscaActualizaciones() или из задачи? Спасибо.

Dav3 04.12.2022 15:18

Другие вопросы по теме