Jak korzystać z nieruchomości?

W porównaniu do poprzedniego kodu dla klasy RulyCanceler, chciałem uruchomić kod używając CancellationTokenSource.

Jak go używać, jak wspomniano w żetonach anulowania , tzn. bez rzucania / łapania wyjątku? Czy mogę skorzystać z właściwości IsCancellationRequested?

Próbowałem użyć go w ten sposób:

cancelToken.ThrowIfCancellationRequested();

I

try
{
  new Thread(() => Work(cancelSource.Token)).Start();
}
catch (OperationCanceledException)
{
  Console.WriteLine("Canceled!");
}

Ale to dało błąd run-time na cancelToken.ThrowIfCancellationRequested(); w metodzie Work(CancellationToken cancelToken):

System.OperationCanceledException was unhandled
  Message=The operation was canceled.
  Source=mscorlib
  StackTrace:
       at System.Threading.CancellationToken.ThrowIfCancellationRequested()
       at _7CancellationTokens.Token.Work(CancellationToken cancelToken) in C:\xxx\Token.cs:line 33
       at _7CancellationTokens.Token.<>c__DisplayClass1.<Main>b__0() in C:\xxx\Token.cs:line 22
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

Kod, który z powodzeniem uruchomiłem, złapał OperationCanceledException w nowym wątku:

using System;
using System.Threading;
namespace _7CancellationTokens
{
  internal class Token
  {
    private static void Main()
    {
      var cancelSource = new CancellationTokenSource();
      new Thread(() =>
      {
         try
         {
           Work(cancelSource.Token); //).Start();
         }
         catch (OperationCanceledException)
         {
            Console.WriteLine("Canceled!");
         }
         }).Start();

      Thread.Sleep(1000);
      cancelSource.Cancel(); // Safely cancel worker.
      Console.ReadLine();
    }
    private static void Work(CancellationToken cancelToken)
    {
      while (true)
      {
        Console.Write("345");
        cancelToken.ThrowIfCancellationRequested();
      }
    }
  }
}
Author: Troyen, 2013-02-25

4 answers

Możesz zaimplementować swoją metodę pracy w następujący sposób:

private static void Work(CancellationToken cancelToken)
{
    while (true)
    {
        if(cancelToken.IsCancellationRequested)
        {
            return;
        }
        Console.Write("345");
    }
}
To wszystko. Zawsze musisz obsłużyć anulowanie samodzielnie-exit from method, gdy jest odpowiedni czas, aby zakończyć (aby Twoja praca i dane były w stanie spójnym)

UPDATE: wolę nie pisać while (!cancelToken.IsCancellationRequested), ponieważ często jest kilka punktów wyjścia, w których można przestać bezpiecznie wykonywać całą pętlę, a pętla zwykle ma jakiś logiczny warunek wyjścia (iteracja nad wszystkimi elementami w kolekcji itp.). Więc Ja uwierz, że lepiej nie mieszać tych warunków, ponieważ mają inne intencje.

 102
Author: Oleksandr Pshenychnyy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-03 12:50:18

@ BrainSlugs83

Nie powinieneś ślepo ufać wszystkiemu, co zostało opublikowane na stackoverflow. Komentarz w kodzie Jens jest nieprawidłowy, parametr nie kontroluje, czy wyjątki są wyrzucane, czy nie.

MSDN jest bardzo jasne, co ten parametr kontroluje, czytałeś go? http://msdn.microsoft.com/en-us/library/dd321703 (v=vs.110). aspx

Jeśli throwOnFirstException jest true, wyjątek zostanie natychmiast propagować się z wezwania do anulowania, uniemożliwiając Pozostałe wywołania zwrotne i anulowane operacje z są przetwarzane. Jeśli throwOnFirstException jest false, przeciążenie to zagreguje wszelkie wyjątki wrzucone do Agregateexception, takie, że jeden callback rzucenie wyjątku nie uniemożliwi innym zarejestrowanym wywołaniom zwrotnym egzekucja.

Nazwa zmiennej jest również błędna, ponieważ Cancel jest wywoływany na CancellationTokenSource, a nie sam token, a źródło zmienia stan każdego tokena, którym zarządza.

 23
Author: user3285954,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-29 21:20:28

Możesz użyć ThrowIfCancellationRequested bez obsługi wyjątku!

Użycie ThrowIfCancellationRequested jest przeznaczone do użycia z zadania (nie wątku). W przypadku użycia w zadaniu nie musisz samodzielnie obsługiwać wyjątku (i uzyskać nieobsługiwany błąd wyjątku). Spowoduje to opuszczenie zadania i zadania.Właściwość iscanceled będzie prawdziwa. Obsługa wyjątków nie jest wymagana.

W twoim konkretnym przypadku zmień wątek na Zadanie.

try
{
  var t = new Task(() => Work(cancelSource.Token));
  t.Start();
}
if (t.IsCancelled)
  Console.WriteLine("Canceled!");
}
 9
Author: Titus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-28 12:06:23

Możesz utworzyć zadanie z tokenem anulowania, gdy aplikacja goto background możesz anulować ten token.

Możesz to zrobić W PCL https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/app-lifecycle

var cancelToken = new CancellationTokenSource();
Task.Factory.StartNew(async () => {
    await Task.Delay(10000);
    // call web API
}, cancelToken.Token);

//this stops the Task:
cancelToken.Cancel(false);

Rozwiązaniem Anther jest Timer użytkownika w Xamarin.Formularze, stop timer, gdy aplikacja goto tło https://xamarinhelp.com/xamarin-forms-timer/

 3
Author: Jesse Jiang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-16 18:09:42