private object _lockObject = new object();
lock (_lockObject)
{
// critical section
using (token.Register(() => token.ThrowIfCancellationRequested())
{
// Do something that might need cancelling.
}
}
Вызов Cancel()
на токене приведет к вызову ThrowIfCancellationRequested()
, так как он был подключен к обратному вызову Register
.Здесь вы можете поместить любую логику отмены, какую захотите.Этот подход хорош, потому что вы можете отменить блокировку вызовов, вызвав условия, которые вызовут завершение вызова.
ThrowIfCancellationRequested создает исключение OperationCanceledException.Вы должны обработать это в вызывающем потоке, иначе весь ваш процесс может быть остановлен.Простой способ сделать это - запустить задачу с помощью класса Task, который объединит все исключения, которые вы сможете обработать в вызывающем потоке.
try
{
var t = new Task(() => LongRunningMethod());
t.Start();
t.Wait();
}
catch (AggregateException ex)
{
ex.Handle(x => true); // this effectively swallows any exceptions
}
Некоторые хорошие вещи здесь , охватывающие совместную отмену