Безотказная утилизация в асинхронном мире - PullRequest
12 голосов
/ 18 февраля 2011

В синхронном мире C # делает управление всеми одноразовыми вещами действительно довольно простым:

using(IDisposable someDisposable=bla.bla())
{
     //do our bidding
}
//don't worry too much about it

Однако, когда мы работаем в асинхронном режиме, мы больше не имеем удобства блока using.Одна из лучших стратегий, с которыми я столкнулся, - это CCR итератор , который позволяет нам использовать асинхронный код «как если бы он был синхронным».Это означает, что мы можем сохранить наш блок using в обработчике итератора и не зацикливаться на сложном решении о том, когда удалять и перехватывать все случаи, когда требуется удаление.

Однако во многих случаяхВызов CCR может показаться излишним, и, честно говоря, хотя я не чувствую себя комфортно с CCR, для непосвященных это может выглядеть как двойная нота.

Поэтому мой вопрос: какие существуют другие стратегии для управленияодноразового использования, когда одноразовые предметы должны сохраняться за пределами непосредственного охвата?

Ответы [ 2 ]

1 голос
/ 18 февраля 2011

Один из подходов состоит в том, чтобы все методы, которые не могли бы сосуществовать с методом удаления, захватывали блокировку во время выполнения и проверяли очередь на предмет объектов, нуждающихся в удалении, когда они заканчивают работу. Затем метод удаления может добавить себя в очередь, использовать TryEnter, чтобы попытаться получить блокировку, удалить объект и удалить его из очереди в случае успеха, или же позволить текущему владельцу блокировки обработать удаление.

0 голосов
/ 19 мая 2014

Оказывается, эта проблема была также в умах дизайнеров языка.

Правильный ответ на этот вопрос теперь заключается в использовании версий асинхронных API на основе Task, которые были предоставлены почти для всех асинхронных операций, в сочетании с новыми ключевыми словами C # async / await. Это позволяет нам сохранять все в пределах действия асинхронных операций:

async Task<int> DoSomething()
{
    using(var foo = new SomeDisposableThing())
    {
         await foo.DoSomethingAsync();
    }
    return 0;
}
...