Предложения для выполнения async ввода / вывода с параллельной библиотекой задач

StackOverflow https://stackoverflow.com/questions/2824235

Вопрос

У меня есть несколько высокопроизводительных файлов передачи файлов, который я писал в C # с использованием модели Async Programming (APM) IDIOM (например, BeginRead/EndRead). Этот код считывает файл с локального диска и записывает его в сокет.

Для лучшей производительности на современном оборудовании важно сохранить более одной нерешенной операции ввода / вывода в полете, когда это возможно. Таким образом, я публикую несколько BeginRead операции в файле, затем, когда вы завершаете, я называю BeginSend на розетке, а когда это завершает, я делаю другой BeginRead в файл. Детали немного сложнее, чем на высоком уровне, это идея.

У меня работает код, основанный на APM, но очень трудно следовать и, вероятно, имеет тонкие ошибки параллелизма. Я хотел бы использовать TPL для этого вместо этого. Я догадался Task.Factory.FromAsync только что сделаю это, но есть поймать.

Все образцы ввода / вывода, которые я видел (наиболее особенно StreamExtensions Класс в параллельных расширении дополнений) Предположим, что нужно прочитать, а затем одна запись. Это не будет работать так, как мне нужно.

Я не могу использовать что-то простое, как Parallel.ForEach или расширение дополнений Task.Factory.Iterate Поскольку задачи ASYNC ввода / вывода не тратят много времени на рабочей нити, поэтому параллель просто запускает еще одну задачу, что приведет к тому, что потенциально десятки или сотни в ожидании операций ввода-вывода; слишком много! Вы можете работать вокруг этого WaitВ ваших задачах, но это вызывает создание обрабатываемого события (объект ядра), а блокирующее ожидание по заданию Wait, которая связана с рабочей нити. Моя реализация на основе APM позволяет избежать обоих этих вещей.

Я играю по разным способам сохранить несколько операций по чтению / записи в полете, и мне удалось сделать это, используя продолжения, которые вызывают метод, который создает другую задачу, но это чувствует себя неловко, и определенно не чувствует идиоматический TPL.

Кто-нибудь еще боролся с такой проблемой с TPL? Какие-либо предложения?

Это было полезно?

Решение

Если вы беспокоитесь о слишком многих потоках, вы можете просто установить ParallelOptions.MaxDegreeOfParallelism до приемлемого номера в вашем звонке Parallel.ForEach.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top