Нам все еще нужен AsyncEnumerator Рихтера? - PullRequest
12 голосов
/ 18 августа 2011

Недавно я наткнулся на класс AsyncEnumerator из библиотеки Power Threading библиотеки Джеффри Рихтера, которая, кажется, решает несколько проблем, с которыми я обычно сталкиваюсь при программировании асинхронных программ.

Идея для этого класса была известна уже давно, и мне интересно, есть ли в текущих версиях .NET / C # встроенная поддержка этого механизма к настоящему времени или все еще необходимо полагаться на третий партийная библиотека? Или, может быть, в более новых версиях .NET есть какой-то альтернативный подход, который упрощает асинхронное программирование так же, как это делает AsyncEnumerator Рихтера?

Или другими словами: есть ли причина не использовать сегодня AsyncEnumerator Рихтера?

Edit:

Некоторые ссылки с информацией об AsyncEnumerator:

Ответы [ 4 ]

18 голосов
/ 19 августа 2011

Да, вы все равно получите выгоду от моего AsyncEnumerator.Новые потоки, представленные в .NET 4 (Tasks, Parallel, PLINQ и т. Д.), Посвящены параллелизму.То есть все они предназначены для того, чтобы взять вычислительную рабочую нагрузку, разделить ее и порождать на несколько потоков, чтобы рабочая нагрузка могла завершиться за меньшее время, чем для выполнения всей рабочей нагрузки 1 поток.Вы можете использовать эти конструкции для одновременного выполнения нескольких операций синхронного ввода-вывода.Однако синхронные операции ввода-вывода приводят к блокировке всех потоков, что затем заставляет пул потоков создавать больше потоков.Таким образом, использование ресурсов вашего приложения стремительно растет, а загрузка ЦП остается очень низкой.Это очень неэффективно для реализации вашего приложения и предотвращает его масштабирование.

Мой AsyncEnumerator полностью инициирует асинхронные операции ввода-вывода, не блокируя какие-либо потоки, так что использование ресурсов вашего приложения остается очень низким, поэтому ваше приложение масштабируетсяотлично.Загрузка ЦП в этом случае также остается низкой, поскольку вы выполняете ввод-вывод;не вычислительная рабочая нагрузка.

В следующей версии .NET новые функции языка async / await (над которыми я работал с Microsoft) позволяют выполнять асинхронный ввод-вывод и, фактически, новые функциисмоделированы очень похоже на мой AsyncEnumerator.Настолько, что вы можете портировать код, который использует мой AsyncEnumerator, на новую модель с очень небольшим количеством изменений исходного кода.

Как кто-то еще отметил, мой AsyncEnumerator по-прежнему предлагает другие функции и работает с .NET 2.0 и более поздними версиями.Так что многие еще долго будут находить его весьма полезным.

9 голосов
/ 18 августа 2011

Очевидная параллель здесь - PLINQ, но сам Рихтер отклоняет это :

Джеффри Рихтер 04.12.2008 в 14:27 quotereply Они очень разные. Parallel.For, в частности, о выполнении кучу параллельные вычисления с параллельным масштабированием для всех процессоров в машине. Мой AsyncEnumerator в основном о выдаче одного или нескольких параллельные операции ввода-вывода без какого-либо потока блоков для их завершить.

Однако CTP C # async здесь может быть полезен, что делает продолжение потоков более разумным, т.е.

var bytesRead = await stream.ReadAsync(...);
Console.WriteLine(bytesRead); // woah! we're on a different thread now!

Здесь компилятор C # переписывает все вокруг await инструкций, так что он становится обратным вызовом / продолжением существующей асинхронной операции (которая должна возвращать «ожидаемое» значение). Надеюсь, что после того, как это будет сделано, это станет более естественным способом написания кода с внутренними задержками из-за асинхронности.

2 голосов
/ 18 августа 2011

.net 4.0 включает инфраструктуру PLINQ и различные другие средства многопоточных вычислений.

Подробнее см. Параллельное программирование в .NET Framework .

0 голосов
/ 14 декабря 2015

Из этого вопроса Задача асинхронного итератора:

Звучит так, как будто вы действительно ищете, что-то вроде IObservable , что-то вроде асинхронного IE на основе толчка IEnumerable .См. Reactive Extensions, также известный как Rx от Microsoft Open Technologies (код, лицензированный под Apache-2.0) (без присоединения), для огромного множества методов, которые работают с IObservable , чтобы заставить его работать как LINQ-to-Объекты и многое другое.

Проблема с IEnumerable заключается в том, что нет ничего, что действительно делает само перечисление асинхронным.Если вы не хотите добавлять зависимость от Rx (что действительно делает IObservable shine), эта альтернатива может работать для вас:

public async Task<IEnumerable<char>> TestAsync(string testString)
{
    return GetChars(testString);
}

private static IEnumerable<char> GetChars(string testString)
{
    foreach (char c in testString.ToCharArray())
    {
        // do other work
        yield return c;
    }
}

, хотя я 'Я хотел бы отметить, что, не зная, что на самом деле ** делается асинхронно, может быть гораздо лучший способ достичь ваших целей.Ни один из размещенного вами кода на самом деле ничего не сделает асинхронно, и я не знаю, является ли что-либо в // do other work асинхронным (в этом случае это не решение вашей основной проблемы, хотя это сделает ваш код компилируемым).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...