Mikhail Sukhov
Что касается реализации, то могу сказать следующее. PlazaStream не должен содержать логики по управлению потоком (thread, и далее по тексту, чтобы не была путаница с потоками данных РТС, которые stream). В нем вообще не должно быть создание никаких потоков. В идеале у него должны быть пару методов Open Close, и события о получении новых данных, удалении, ошибке и т.д. А вот уже управлять стримами (в том числе и создавать единый поток для обработки всех стримов) нужно в PlazaTrader.
Дело в том, что работа с плазовским стримом построена по принципу windows message loop: в неком методе программа вызывает метод CP2ConnectionClass.ProcessMessage(out cookie, PollInterval) в бесконечном цикле, а вся информация приходит через события. Если выводить создание и управление thread'ами, это нужно делать в отдельном классе. Иначе, если придется подключаться к стримам в нескольких местах, придется дублировать много кода.
Mikhail Sukhov
1. PlazaStreamName. Енумераторы обычно окончиваются на множественное число. Плюс по логике это никакие не Name (енумы не могут содержать стринги). Я бы назвал PlazaStreams.
2. PlazaReplicationSchemes
Насчет Name вы правы - уберу. По поводу множественного числа: рекомендация MS - енумераторы в множественном числе, только если они битовые флаги, поэтому все-таки настаиваю на единственном.
Mikhail Sukhov
3. А вот тут самое интересно. А для чего собственно писали PlazaTable и мучались с метаданными? Надо использовать по максимуму ООП. Я бы передавал в стрим PlazaTable.
Я помню о настраиваемости. Пока в черновом варианте я передаю путь к файлу, чтобы сразу можно было протестировать логику подключения, опроса, получения сообщений и т.д.
С метаданными такая вещь: стримы в Плазе настраиваются из файлов, даже по умолчанию (методы TableSet.InitFromIni / TableSet.InitFromIni2). Если передавать классу PlazaStream в конструкторе PlazaTable, тогда внутри PlazaStream некий класс TableConfigParser должен будет генерить файл с нужной схемой, чтобы передать ее TableSet.InitFromIni. Здесь такой момент: предлагаю в SpecialFolder.ApplicationData создать путь Stocksharp\PlazaTrader\Scheme, в котором хранить свои конфиг-схемы-файлы или их создавать в папке TEMP. Создавать их в подпапке самой Плазы не стоит: требуется админский доступ.
Mikhail Sukhov
4. Такие вещи как PlazaStream неплохо бы делать IDisposable. Советую наследоваться от Disposable (Ecng.Common), он по-функциональнее.
Сделаю
Mikhail Sukhov
1. Лучше стандартные, которые в .NET. Честно говоря я не помню случаем, когда бы использовал другие исключения, вместо ArgExp, ArgOutExp, ArgNullExp, InvOptExp. Все остальные какие-то натянутые, и далекие от простых будней. Разделения на внешний и внутренний не понял.
Чтобы понимать в будущем, в каких случаях мы выкидываем PlazaException?
Mikhail Sukhov
2. А вот тут не могу сказать. Как удобнее, так и надо. Тоесть Плаза за раз отсылает только одну строчку?
Насколько я понял, есть два варианта:
- По одной строчке в событии StreamDataInserted. В этом случае ты получаешь в качестве параметра CP2Record, который потом нужно опрашивать для каждой колонки с помощью методов GetValAsХХХ(string fieldName) / GetValAsХХХByIndex(uint fieldIndex)
- Подсоединять к стриму CP2DataBufferClass, который накапливает данные. Потом у него нужно вызывать метод get_TableRecords(string tableName), который возвращает CP2RecordEnumClass, что есть IEnumerable<CP2Record>
И там, и сям Hello, COM world!
На мой взгляд вызовы GetValAsХХХ(string fieldName) / GetValAsХХХByIndex(uint fieldIndex) нужно реализовать внутри PlazaStream, а мне чтобы дальше писать это класс нужно понимать:
- PlazaStream - это служебный класс, или им смогут пользоваться клиенты (читай, сторонние разработчики, использующие PlazaTrader)?
- В каком виде выдавать данные классам, которые будут использовать PlazaStream? Через события по одной строчке с конвертацией CP2Record в массив object'ов? Или попробовать сделать что-то типа реализации интерфейса IDataReader с использованием CP2DataBufferClass?
И последнее насчет фильтрации данных в потоке. Есть предложение это тоже сделать внутри PlazaStream. Тогда при конвертации данных с помощью GetValAsХХХ() / GetValAsХХХByIndex() можно будет проверять только колонки, по которым идет фильтрация, и, если запись не подходит, не выдавать ее клиентскому коду.