2015-12-06 3 views
1

J'ai une méthode dans laquelle je ne contrôle pas (supposons qu'il vient d'une autre bibliothèque):Existe-t-il un moyen d'annuler une tâche C# non annulable sans attendre le délai si la tâche se termine plus tôt?

private static void DoWork() 
{ 
    // I have no control over this method 
    while (true) 
    { 
     Console.WriteLine("Still working"); 
    } 
} 

Et je veux attendre un peu de temps (par exemple 20 secondes) et si le travail n'est pas fini dans ce temps d'arrêter le code.

Ce que j'ai essayé jusqu'à présent:

  • modèle utilisant la tâche d'annulation n'est pas une option pour moi parce que je ne contrôle pas la méthode que je suis exécutais

  • En utilisant seulement la Task classe n'est pas une option parce que je ne peux pas arrêter l'exécution de la tâche sans utiliser annulation jeton

    var taskToWaitAndKill = 
        Task.Factory.StartNew(DoWork); 
    taskToWaitAndKill.Wait(20000); // 20 seconds 
    // The task cannot be stopped (aborted) and still runs... 
    
  • aide la classe Thread, l'attendre et l'abandonner n'est pas une option car j'ai besoin d'attendre les 20 secondes avant d'arrêter le code.

    var thread = new Thread(DoWork); 
    thread.Start(); 
    Thread.Sleep(20000); 
    thread.Abort(); 
    

Ma question est-il un moyen en C# attendre nombre fixe de millisecondes pour un code d'exécution et si le code se termine plus tôt de ne pas attendre plus longtemps?

+2

Doit-on annuler l'opération? Ou peut-il continuer en arrière-plan pendant que vous reprenez votre travail? –

+1

Voir [si cette réponse] (http://stackoverflow.com/a/25684549/1870803) aide. –

Répondre

2

Utilisation de la classe de fil, il attend et il est avorter pas une option parce que je dois attendre toutes les 20 secondes avant d'arrêter le code.

faire différemment et vous pouvez le faire:

var timeout = TimeSpan.FromSeconds(20); 
var started = DateTime.UtcNow; 
var thread = new Thread(DoWork); 
thread.Start(); 
while (thread.IsAlive && DateTime.UtcNow - started < timeout) 
{ 
    Thread.Sleep(10); 
    // Do whatever here 
} 

// timeout occured, aborting 
if (thread.IsAlive) 
    thread.Abort(); 

Cependant, tuant un fil par Abort est un dangerous operation, pourrait causer des surprises. Si vous devez vraiment exécuter des codes étrangers, que vous ne pouvez pas contrôler (par exemple, des plugins tiers), vous devez créer un AppDomain pour eux. En cas d'erreur (y compris ThreadAbortException) vous pouvez décharger le AppDomain en toute sécurité.