Как правильно отменить задачу и поймать OperationCanceledException? - PullRequest
0 голосов
/ 16 февраля 2019

Этот вопрос уже задавался, но я все еще не получил его ... Я пытаюсь отменить задачу, но когда я включаю ThrowIfCancellationRequested (), она не перехватывается, и если я ее не включаю,GUI зависает ...

Вот мой код, который запускается без ThrowIfCancellationRequested (), но замораживает GUI:

 public void StartProcess(double myvariable)
    {
        tokenSource = new CancellationTokenSource();
        CancellationToken token = tokenSource.Token;

        processThread = Task.Factory.StartNew(() =>
        {
            while (true)
            {
                //Do some work with myvariable

                if (token.IsCancellationRequested)
                {
                    break;
                }
            }
        }, token);
    }

И код с ThrowIfCancellationRequested (), который не перехватывается,отладчик останавливается на строке token.ThrowIfCancellationRequested ():

 public void StartProcess(double myvariable)
    {
        tokenSource = new CancellationTokenSource();
        CancellationToken tokenDispatcher = tokenSource.Token;

        processThread = Task.Factory.StartNew(() =>
        {
            try
            {
                while (true)
                {
                    //Do some work with myvariable

                    if (token.IsCancellationRequested)
                    {
                        token.ThrowIfCancellationRequested();
                        break;
                    }
                }
            }
            catch (AggregateException ae)
            {
                    if (ae.InnerException is OperationCanceledException)
                    {
                        Console.WriteLine("Process Thread Cancelled");
                    }
                    else
                    {
                        Console.WriteLine("ERROR");
                    }
            }
        }, token);
    }

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

1 Ответ

0 голосов
/ 16 февраля 2019

ThrowIfCancellationRequested - это правильный способ отменить задание.Что вам нужно понять, так это то, что при отмене Задачи не будет никаких исключений.Только Status задачи будет установлено на Canceled.Блок try catch у вас внутри задачи ничего не даст.Чтобы получить исключение, вам нужно дождаться Задачи в асинхронном методе или использовать метод Wait, чтобы дождаться завершения задачи.Использовать метод Wait не рекомендуется, поскольку вы блокируете текущий поток до завершения задачи.

Ниже приведено предложение о том, как можно реализовать это из своего кода.

public static Task StartProcess(double myvariable)
{
   tokenSource = new CancellationTokenSource();
   CancellationToken token = tokenSource.Token;

   return Task.Factory.StartNew(() =>
   {
      while (true)
      {
         //Do some work with myvariable

         token.ThrowIfCancellationRequested();
      }
   }, token);
}

public async Task ExecuteProcess(double myvariable)
{
   try
   {
      await StartProcess(myvariable);
   }
   catch (OperationCanceledException ex)
   {
      Console.WriteLine("Process Thread Canceled");
   }
   catch (Exception ex)
   {
      Console.WriteLine("ERROR");
   }
}

Метод ExecuteProcessдемонстрирует, как вам нужно вызвать вашу функцию, чтобы получить исключение.Таким образом, вы также предотвращаете блокировку графического интерфейса пользователя, если вызываете метод из потока пользовательского интерфейса.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...