Вот код:
private void OnLogUpdate(ErrorTypes err, string message)
{
this.Log(new LogMessage(this, DateTime.Now, err, message));
}
public T400()
{
plaza = new PlazaTrader(this.StrategyParameters.PlazaRouterPath.To<IPEndPoint>());
this.candleManager = new CandleManager(plaza);
logManager = new LogManager();
logManager.Sources.Add(this);
}
T400 это робот, по сути класс-инфраструктура для запуска стратегии, чтобы он тоже мог писать логи реализуется ILogSource. На старте робота выполняется:```csharp guiLogListener = new GuiLogListener(_logWindow); t400.AddLogListener(guiLogListener);
Потом, при выполнении OnLogUpdate ошибка: [System.ArgumentNullException] = {"Значение не может быть неопределенным.\r\nИмя параметра: obj"}
Вот стэктрэйс:
в Ecng.Xaml.XamlHelper.GuiSync(DispatcherObject obj, Action action)
в StockSharp.Xaml.GuiLogListener.OnWriteMessage(LogMessage message)
в StockSharp.Algo.Logging.LogListener.WriteMessage(LogMessage message)
в StockSharp.Algo.Logging.LogManager.#=qrUj$Ns0mMAxxqh0k0FFJLB8wrKr4pz7DsmdCpRVKh18=.#=q3S_X0XbExHKU68uzjbFQVxw4VT4yOdgZvBt8Dr1nZXc=(ILogListener #=qeUzjoy2OxlhpLB1gDjK5qQ==)
в Ecng.Collections.CollectionHelper.ForEach(IEnumerable`1 source, Action`1 action)
в StockSharp.Algo.Logging.LogManager.#=qm2awVrrxMn_7KT6KAHw0Wg==(LogMessage #=qJiXkieLb13i$V63GpKExqw==)
в Skynet.T400.OnLogUpdate(ErrorTypes err, String message)
Собственно вопрос: что передается в GuiSync в качестве DispatcherObject и почему все ломается.
Второй вопрос: как правильно в такой ситуации реализовать ILogSource, кто будет Parent, кто Childs, и зачем там Guid?
P.S. Ошибка появилась оч недавно, после последнего обновления референсов
Комментарии (16)
Вход или Создать аккаунт, Войдите или зарегистрируйтесь, чтобы оставить комментарий
Guid пропишите Guid.NewGuid() в конструкторе остальное верните null
Посмотрите это ради примера
Короче это бага в последней сборке похоже. Если переменная _logWindow имеет тип MonitorWindow то все прекрасно работает, если тип LogWindow то ломается. Странно, ведь LogWindow тоже является DispatcherObject'ом. Я исходников StockSharp.Xaml не имею, потому посмотреть что там не могу.
LogWindow не наследует ILogListener
Конструктор GuiLogListener принимает типы LogControl, LogWindow, MonitorWindow, это собственно окна, которые будут отображать логи. Раньше с LogWindow все работало, теперь нет. Ошибка возникает в рантайме, возможно так какое-нибудь явное преобразование типов стоит, обычно оно такие ошибки дает.
В последней версии ошибка. Исправил в ближайшее время.
Там еще одна ошибка есть жесткая: при попытке отключится прога зависает намертво. Я выяснил что это именно связано с логгированием. То есть, если не подключать логгирование```csharp guiLogListener = new GuiLogListener(_logWindow); logManager.Listeners.Add(guiLogListener);
Поправка: Если перед отключением от плазы сделать logManager.Sources.Remove(t400); то все нормально становится. Видимо дело в том, как я реализовал ILogSource у T400
Каждый раз будет создаваться новый Guid. Сделайте в конструкторе Id = Guid.NewGuid() и оставьте set; get; по умолчанию.
Не помогло=(
Подозреваю, что ошибка не в S#.
Я вроде как понял:
Проблема в том, что Log вызывается не GuiAsync. Я впринципе не могу вызвать его GuiAsync, т.к. это функция для некоторого DispatcherObject, окна тоесть, а я обрабатываю внутри T400.
Я реализовывал ILogSource для MainWindow, та же проблема возникает. Но если написать так
то все норм.
ILogListener все тот же? Тогда это тянется отсюда же http://stocksharp.com/posts/m/11605/
В прикрепленном файле посмотрите, эта ошибка с зависанием реализована для MainWindow из примера SimpleGUI.
После последнего обновления StockSharp.Algo первая ошибка с LogWindow решилась. Проблема с зависанием осталась.
А зависание от чего происходит?
Зависание возникает при вызове лога в момент дисконнекта:
Причем если обернуть GuiAsync, то не зависает. Это оочень странно, т.к. вроде как внутри GuiLogListener вызов лога оборачивается в GuiAsync автоматически.