2014-09-15 5 views
1

с использованием CancellationTokenSource на задаче Thats получает блокировкуCancellationToken для задачи, которая приобретает замок

Если поток получает блокировку, когда дезактивация встречается, это не освобождает замок

Кстати, нить необходимо немедленно прекратить, без finnishing работы

Это пример такого кода:

var cancellationTokenSource = new CancellationTokenSource; 

Task.Run(new Action (() => 
{ 
    while(true) 
    { 
     lock (locker) 
     { 
      DoSomething();  
     } 

     DoAnotherThing(); 

     Task.Delay(1000, cancellationTokenSource.Token);  
    } 
}), cancellationTokenSource.Token); 

Я нашел несколько способов руки ле это, но я хотел бы услышать некоторые предложения

Благодарности

EDIT: Для того, чтобы ответить на вопрос @spender, это реализация мысль о (укороченный):

object locker = new object(); 
    var cancellationTokenSource = new System.Threading.CancellationTokenSource; 
    var token = cancellationTokenSource.Token; 

    Task.Run(new Action (() => 
    { 


     while(true) 
     { 
      lock (locker) 
      { 
       using (token.Register(() => token.ThrowIfCancellationRequested())) 
       { 
        break; 
       }; 

       DoSomething();  
      } 

      DoAnotherThing(); 

      Task.Delay(1000, cancellationTokenSource.Token);  
     } 
    }), cancellationTokenSource.Token); 
+3

Я хотел бы услышать ваши «несколько способов» ...? – spender

+0

Ответил в редактировании оригинального сообщения –

ответ

0

Вы никогда не позволяя завершить действие вашей полезной нагрузки. Отмена выполняемой задачи - это не то же самое, что вызов Thread.Abort (который вы не хотите делать в любом случае). Вы должны распространять отмену на все, что, вероятно, продолжит выполнение/ожидание/блокирование в течение любого значительного времени после отмены сигнала.

while(!cancellationTokenSource.Token.IsCancellationRequested) 
{ 
    lock (locker) 
    { 
     DoSomething(); //consider passing the token here if it takes a while... 
    } 

    DoAnotherThing(); //and here... 
    try 
    { 
     Task.Delay(1000, cancellationTokenSource.Token);  
    } 
    catch(TaskCanceledException) 
    { 
     break; 
    } 
} 
+0

Спасибо, но это не отвечает на мой вопрос. Мне нужна задача, чтобы немедленно остановиться, не дожидаясь ее завершения. –

+2

@GuyLevin: Невозможно немедленно остановить задачу. Единственный способ сделать это - Thread.Abort. [Thread.Abort - мерзость] (http://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort), который никогда не должен был быть включен. – spender

+1

@GuyLevin. Никакая волшебная пуля не позволяет вам немедленно отменить, вам нужно проверить время, требуемое для отсрочки, и бросить. –