#.net #multithreading #.net-4.0 #semaphore
#.net #многопоточность #.net-4.0 #семафор
Вопрос:
Как я должен структурировать попытку / finally при использовании SemaphorSlim с токеном отмены, чтобы OperationCancelledException обрабатывалось правильно? В варианте A отмена источника токена вызывает исключение OperationCancelledException, но не вызывает Release(). В варианте B отмена источника токена вызывает исключение OperationCancelledException и вызывает Release().
// option A:
_semaphorSlim.Wait( _cancellationTokenSource.Token );
try
{
// do work here
}
finally
{
_semaphorSlim.Release();
}
// option B:
try
{
_semaphorSlim.Wait( _cancellationTokenSource.Token );
// do work here
}
finally
{
_semaphorSlim.Release();
}
Ответ №1:
Вариант A здесь более правильный. Вам не нужно Release
SemaphoreSlim
при отмене, поскольку вы фактически никогда не получаете и не увеличиваете его количество. Таким образом, вы не хотите выпускать, если ваш Wait
вызов действительно не был успешным.
С этой страницы MSDN об использовании Semaphore и SemaphoreSlim:
Ответственность программиста заключается в том, чтобы поток не освобождал семафор слишком много раз. Например, предположим, что максимальное количество семафоров равно двум, и что поток A и поток B оба входят в семафор. Если ошибка программирования в потоке B заставляет его дважды вызывать Release, оба вызова завершаются успешно. Количество в семафоре заполнено, и когда поток A в конечном итоге вызывает Release, генерируется исключение SemaphoreFullException.
Ответ №2:
-Извините за поздний ответ, надеюсь, это может кому-то помочь. Поскольку мы не можем гарантировать момент отмены и когда этот код может быть сбит, нам нужно использовать опцию A. Затем в предложении finally проверьте, использовался ли токен отмены или нет. Если оно было использовано, то не освобождайте семафор.