В этот пост в блоге, Stephan Toub описывает новую функцию, которая будет включена в .NET 4.6, которая добавляет еще одно значение TaskCreationOptions и TaskContinuationOptions перечисления, называемые RunContinuationsAsynchronously
.
Он объясняет:
"Я говорил о ветвлении вызова методов {Try} Set * на TaskCompletionSource, что любые синхронные продолжения задачи TaskCompletionSources можно запустить синхронно, так как часть вызова. Если бы мы вызывали SetResult здесь, удерживая блокировка, затем будут выполняться синхронные продолжения этой Задачи удерживая замок, и это может привести к очень серьезным проблемам. Итак, удерживая блокировку, мы захватываем объект TaskCompletionSource для завершаться, но мы еще не закончили его, откладывая это до тех пор, пока блокировка была выпущена"
И дает следующий пример для демонстрации:
private SemaphoreSlim _gate = new SemaphoreSlim(1, 1);
private async Task WorkAsync()
{
await _gate.WaitAsync().ConfigureAwait(false);
try
{
// work here
}
finally { _gate.Release(); }
}
Теперь представьте, что у вас много вызовов WorkAsync:
await Task.WhenAll(from i in Enumerable.Range(0, 10000) select WorkAsync());
Мы только что создали 10 000 вызовов WorkAsync, которые будут соответствующим образом сериализуется на семафоре. Одна из задач введите критическую область, а остальные будут стоять в очереди на WaitAsync, внутри SemaphoreSlim эффективно запускает задачу который будет завершен, когда кто-то вызовет Release. Если Release завершил это Задача синхронно, тогда, когда первая задача вызывает Release, она будет синхронно запускать вторую задачу, а когда она вызывает Release, он будет синхронно запускать третью задачу, и поэтому на. Если раздел "//работа здесь" выше кода не содержит ждет, что уступит, тогда мы потенциально собираемся погрузиться в ныряние здесь и в конечном итоге потенциально удалите стек.
Мне сложно усвоить ту часть, где он говорит о продолжении синхронного продолжения.
Вопрос
Как это может привести к погружению в стек? Более того, а что эффективнее делать RunContinuationsAsynchronously
для решения этой проблемы?