Вот код:
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. Ошибка появилась оч недавно, после последнего обновления референсов
Kommentare (16)
Anmelden oder Konto erstellen, Melden Sie sich an oder registrieren Sie sich, um einen Kommentar zu hinterlassen
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 автоматически.