2017-02-04 1 views
-4

J'utilise une méthode asynchrone. Comment puis-je arrêter son exécution lorsqu'un temporisateur déclenche un événement de temporisation?Comment arrêter l'exécution de la méthode async dans C#?

Mon code:

public async Task<object> Method() 
{ 
    cts = new CancellationTokenSource(); 
    try 
    { 
     timer = new System.Timers.Timer(3000); 
     timer.Start(); 
     timer.Elapsed += (sender, e) => 
     { 
      try 
      { 
       timer_Elapsed(sender, e, cts.Token, thread); 
      } 
      catch (OperationCanceledException) 
      { 
       return; 
      } 
      catch (Exception ex) 
      { 
       return; 
      } 
     }; 
     await methodAsync(cts.Token); 
     return "message"; 
    } 
    catch (OperationCanceledException) 
    { 
     return "cancelled"; 
    } 
    catch (Exception ex) 
    { 
     return ex.Message; 
    } 
} 

// Async Call 
public async Task<object> methodAsync(CancellationToken ct) 
{ 
    try 
    { 
     pdfDocument = htmlConverter.Convert("path", ""); 
    } 
    catch(Exception ex) 
    { 
     return x.Message; 
    } 
} 

// Timer event 
void timer_Elapsed(object sender, ElapsedEventArgs e, CancellationToken ct) 
{ 
    cts.Cancel(); 
    ct.ThrowIfCancellationRequested(); 
} 
+2

Vous semblez essayer d'annuler le code 'htmlConverter.Convert (" path "," ")'. Il n'y a aucun moyen d'annuler ce code car le code qui annule doit être capable de répondre au jeton d'annulation. La seule réponse est donc que vous devez lancer un nouveau processus et le tuer si vous devez annuler. Sinon, la seule action sécurisée consiste à laisser ce code s'exécuter complètement. – Enigmativity

+0

Je n'essaie pas d'annuler ce 'pdfDocument = htmlConverter.Convert (" path "," ");' code. Essayez simplement de supprimer la fonction methodAsync(). Y a-t-il un moyen? –

+0

La seule chose qui se passe dans la fonction 'methodAsync' est l'appel à' .Convert', donc l'arrêter est la même chose que stopper l'autre. Vous ne pouvez pas forcer la tâche/le fil à annuler en toute sécurité. Vous devez être en mesure de répondre au jeton d'annulation pour que cela fonctionne. – Enigmativity

Répondre

0

Je pense que vous pouvez essayer de mentionner quand l'annuler. Quelque chose comme

cts.CancelAfter(TimeSpan.FromMilliseconds(5000)); 

De même, vous devez utiliser le jeton d'annulation dans les méthodes appelées. C'est quand vous saurez quand annuler.

1

Voici comment annuler une tâche fonctionne:

public async Task<object> Method() 
{ 
    cts = new CancellationTokenSource(); 
    await methodAsync(cts.Token); 
    return "message"; 
} 

public Task<object> methodAsync(CancellationToken ct) 
{ 
    for (var i = 0; i < 1000000; i++) 
    { 
     if (ct.IsCancellationRequested) 
     { 
      break; 
     } 
     //Do a small part of the overall task based on `i` 
    } 
    return result; 
} 

Vous devez répondre à la modification de la propriété de ct.IsCancellationRequested savoir quand pour annuler la tâche. Il n'existe aucun moyen sûr pour un thread/tâche d'annuler un autre thread/tâche.

Dans votre cas, il semble que vous essayez d'appeler une seule méthode qui ne connaît pas le CancellationToken. Vous ne pouvez donc pas annuler cette tâche en toute sécurité. Vous devez laisser le thread/tâche continuer à l'achèvement.