/// <summary> /// Create a new activity session. /// </summary> /// <param name="product">Product type.</param> public void CreateSession(Products product) { if (_sessionId != 0) { throw new InvalidOperationException(); } var authClient = AuthenticationClient.Instance; _sessionId = Invoke(f => f.CreateSession(product, authClient.IsLoggedIn ? authClient.SessionId : Guid.Empty)); _pingTimer = ThreadingHelper.Timer(() => { try { lock (_pingSync) { if (_sessionId == 0) { return; } Invoke(f => f.Ping(_sessionId)); } } catch (Exception ex) { ex.LogError(); } }).Interval(TimeSpan.FromMinutes(10)); }
public DiagramPanel() { InitializeComponent(); Palette.PaletteElements = ConfigManager.GetService <CompositionRegistry>().DiagramElements; _timer = ThreadingHelper.Timer(() => { lock (this) { if (!_needToSave) { return; } GuiDispatcher.GlobalDispatcher.AddAction(Save); _needToSave = false; } }).Interval(TimeSpan.FromSeconds(5)); if (!DiagramEditor.IndicatorTypes.IsEmpty()) { return; } DiagramEditor.IndicatorTypes.AddRange(Configuration.Extensions.GetIndicatorTypes()); }
private void EnsureInit() { if (_refreshTimer != null) { return; } Refresh(); var subscriptions = Invoke(f => f.GetSubscriptions(SessionId, DateTime.MinValue)); foreach (var subscription in subscriptions) { _subscriptions.Add(subscription.Id, subscription); } var backtests = Invoke(f => f.GetBacktests(SessionId, DateTime.Today - TimeSpan.FromDays(5), DateTime.UtcNow)); foreach (var backtest in backtests) { _backtests.Add(backtest.Id, backtest); } _refreshTimer = ThreadingHelper .Timer(Refresh) .Interval(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)); }
public MainWindow() { InitializeComponent(); Title = Title.Put(LocalizedStrings.Str3200); Loaded += OnLoaded; _dataTimer = ThreadingHelper .Timer(OnDataTimer) .Interval(TimeSpan.FromMilliseconds(1)); Theme.SelectedIndex = 1; SeriesEditor.Settings = new CandleSeries { CandleType = typeof(TimeFrameCandle), Arg = TimeSpan.FromMinutes(1) }; ConfigManager.RegisterService <IMarketDataProvider>(_testMdProvider); ConfigManager.RegisterService <ISecurityProvider>(_securityProvider); Theme.ItemsSource = DXTheme.Themes.Where(t => t.ShowInThemeSelector); ThemeExtensions.ApplyDefaultTheme(); }
public CsvExtendedInfoStorageItem(string fileName, string[] fields) { if (fileName.IsEmpty()) { throw new ArgumentNullException(nameof(fileName)); } if (fields == null) { throw new ArgumentNullException(nameof(fields)); } if (fields.IsEmpty()) { throw new ArgumentOutOfRangeException(nameof(fields)); } _fileName = fileName; _fields = fields; ThreadingHelper .Timer(() => { try { OnFlush(); } catch (Exception ex) { ex.LogError(); } }) .Interval(TimeSpan.FromSeconds(5)); }
private void StartTimer() { if (_timer != null) { return; } var period = ReConnectionSettings.Interval; var needHeartbeat = HeartbeatInterval != TimeSpan.Zero; var time = TimeHelper.Now; var lastHeartBeatTime = TimeHelper.Now; var sync = new SyncObject(); var isProcessing = false; if (needHeartbeat) { _canSendTime = true; period = period.Min(HeartbeatInterval); } _timer = ThreadingHelper .Timer(() => { lock (sync) { if (isProcessing) { return; } isProcessing = true; } try { var now = TimeHelper.Now; var diff = now - time; if (needHeartbeat && now - lastHeartBeatTime >= HeartbeatInterval) { ProcessHeartbeat(); lastHeartBeatTime = now; } ProcessReconnection(diff); time = now; } catch (Exception ex) { ex.LogError(); } finally { lock (sync) isProcessing = false; } }) .Interval(period); }
/// <inheritdoc /> public void Login(Products?product, Version version, string login, SecureString password) { if (login.IsEmpty()) { throw new ArgumentNullException(nameof(login)); } if (password.IsEmpty()) { throw new ArgumentNullException(nameof(password)); } Guid sessionId; if (product == null) { sessionId = Invoke(f => f.Login(login, password.To <string>())); sessionId.ToErrorCode().ThrowIfError(); NullableSessionId = sessionId; UserId = Invoke(f => f.GetId(sessionId)); } else { var tuple = Invoke(f => version == null ? f.Login2(product.Value, login, password.To <string>()) : f.Login3(product.Value, version.To <string>(), login, password.To <string>())); tuple.Item1.ToErrorCode().ThrowIfError(); NullableSessionId = tuple.Item1; UserId = tuple.Item2; } if (product != null) { _pingTimer = ThreadingHelper.Timer(() => { try { var session = NullableSessionId; if (session == null) { return; } lock (_pingSync) { Invoke(f => f.Ping(session.Value)); } } catch (Exception ex) { ex.LogError(); } }).Interval(TimeSpan.FromMinutes(10)); } }
private void EnsureInit() { lock (_syncObject) { if (_refreshTimer != null) { return; } var processSubscriptions = true; _refreshTimer = ThreadingHelper.Timer(() => { lock (_syncObject) { if (_isProcessing) { return; } _isProcessing = true; } try { Refresh(); if (processSubscriptions) { var subscriptions = Invoke(f => f.GetSubscriptions2(SessionId, DateTime.MinValue)); foreach (var subscription in subscriptions) { _subscriptions.Add(subscription.Id, subscription); } //var backtests = Invoke(f => f.GetBacktests(SessionId, DateTime.Today - TimeSpan.FromDays(5), DateTime.UtcNow)); //foreach (var backtest in backtests) //{ // _backtests.Add(backtest.Id, backtest); //} processSubscriptions = false; } } catch (Exception ex) { ex.LogError(); } finally { lock (_syncObject) _isProcessing = false; } }).Interval(TimeSpan.Zero, TimeSpan.FromMinutes(1)); } }
private UserConfig() { MainFolder = BaseApplication.AppDataPath; LogsPath = Path.Combine(MainFolder, "Logs"); CandleSeriesDumpPath = Path.Combine(MainFolder, "CandleSources", "Dump"); //UIPath = Path.Combine(MainFolder, "UI"); //LayoutFile = Path.Combine(UIPath, "Layout.xml"); StrategiesAssemblyPath = Path.Combine(MainFolder, "Strategies", "Assemblies"); StrategiesTempPath = Path.Combine(MainFolder, "Strategies", "Temp"); ExecutionStoragePath = Path.Combine(MainFolder, "TradingData"); #if DEBUG CompositionsPath = Path.Combine(@"..\..\", "Compositions"); #else CompositionsPath = Path.Combine(MainFolder, "Compositions"); #endif TryCreateDirectory(); _configFile = Path.Combine(MainFolder, "studio_config.xml"); var logSettingsFile = Path.Combine(LogsPath, "logManager.xml"); var logManager = ConfigManager.GetService <LogManager>(); if (File.Exists(logSettingsFile)) { logManager.Load(new XmlSerializer <SettingsStorage>().Deserialize(logSettingsFile)); } if (logManager.Listeners.Count == 0) { logManager.Listeners.Add(new FileLogListener { LogDirectory = LogsPath, SeparateByDates = SeparateByDateModes.SubDirectories, Append = true, MaxLength = 10000000, MaxCount = 3 }); } new XmlSerializer <SettingsStorage>().Serialize(logManager.Save(), logSettingsFile); logManager.Sources.Add(this); //IPersistableService svc = this; //if (svc.GetReferences() == null) // svc.SetReferences(GetDefaultReferences()); ConfigManager.RegisterService <IPersistableService>(this); _timer = ThreadingHelper .Timer(Save) .Interval(TimeSpan.FromSeconds(60)); AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; }
/// <summary> /// Initializes a new instance of the <see cref="StorageMessageAdapter"/>. /// </summary> /// <param name="innerAdapter">The adapter, to which messages will be directed.</param> /// <param name="entityRegistry">The storage of trade objects.</param> /// <param name="storageRegistry">The storage of market data.</param> public StorageMessageAdapter(IMessageAdapter innerAdapter, IEntityRegistry entityRegistry, IStorageRegistry storageRegistry) : base(innerAdapter) { if (entityRegistry == null) { throw new ArgumentNullException("entityRegistry"); } if (storageRegistry == null) { throw new ArgumentNullException("storageRegistry"); } _entityRegistry = entityRegistry; _storageRegistry = storageRegistry; Drive = _storageRegistry.DefaultDrive; ThreadingHelper.Timer(() => { foreach (var pair in GetTicks()) { GetStorage(pair.Key, typeof(ExecutionMessage), ExecutionTypes.Tick).Save(pair.Value); } foreach (var pair in GetOrderLog()) { GetStorage(pair.Key, typeof(ExecutionMessage), ExecutionTypes.OrderLog).Save(pair.Value); } foreach (var pair in GetTransactions()) { GetStorage(pair.Key, typeof(ExecutionMessage), ExecutionTypes.Order).Save(pair.Value); } foreach (var pair in GetOrderBooks()) { GetStorage(pair.Key, typeof(QuoteChangeMessage), null).Save(pair.Value); } foreach (var pair in GetLevel1()) { GetStorage(pair.Key, typeof(Level1ChangeMessage), null).Save(pair.Value); } foreach (var pair in GetCandles()) { GetStorage(pair.Key.Item1, pair.Key.Item2, pair.Key.Item3).Save(pair.Value); } var news = GetNews().ToArray(); if (news.Length > 0) { _storageRegistry.GetNewsMessageStorage(Drive, Format).Save(news); } }).Interval(TimeSpan.FromSeconds(10)); }
private void TryStartTimer() { lock (_sync) { if (!_isFlushing && _flushTimer == null) { _flushTimer = ThreadingHelper .Timer(OnFlush) .Interval(_flushInterval); } } }
public override void SendInMessage(Message message) { switch (message.Type) { case MessageTypes.Reset: { CloseTimer(); break; } case MessageTypes.Connect: { if (_marketTimer != null) throw new InvalidOperationException(LocalizedStrings.Str1619); lock (_marketTimerSync) { _isMarketTimeHandled = true; _marketTimer = ThreadingHelper .Timer(() => { // TimeMsg required for notify invoke MarketTimeChanged event (and active time based IMarketRule-s) // No need to put _marketTimeMessage again, if it still in queue. lock (_marketTimerSync) { if (_marketTimer == null || !_isMarketTimeHandled) return; _isMarketTimeHandled = false; } _marketTimeMessage.LocalTime = TimeHelper.Now; RaiseNewOutMessage(_marketTimeMessage); }) .Interval(_parent.MarketTimeChangedInterval); } break; } case MessageTypes.Disconnect: { if (_marketTimer == null) throw new InvalidOperationException(LocalizedStrings.Str1856); CloseTimer(); break; } } base.SendInMessage(message); }
/// <summary> /// Process <see cref="MessageAdapterWrapper.InnerAdapter"/> output message. /// </summary> /// <param name="message">The message.</param> protected override void OnInnerAdapterNewOutMessage(Message message) { switch (message.Type) { case MessageTypes.Connect: { if (((ConnectMessage)message).Error == null) { lock (_timeSync) _prevState = _currState = ConnectionStates.Connected; // heart beat is disabled if (InnerAdapter.HeartbeatInterval == TimeSpan.Zero) { break; } lock (_timeSync) { _canSendTime = true; _heartBeatTimer = ThreadingHelper.Timer(OnHeartbeatTimer).Interval(InnerAdapter.HeartbeatInterval); } } else { lock (_timeSync) _prevState = _currState = ConnectionStates.Failed; } break; } case MessageTypes.Disconnect: { lock (_timeSync) { _prevState = _currState = ConnectionStates.Disconnected; if (_heartBeatTimer != null) { _heartBeatTimer.Dispose(); _heartBeatTimer = null; } } break; } } base.OnInnerAdapterNewOutMessage(message); }
/// <summary> /// To subscribe for news. /// </summary> public void SubscribeNews() { _newsTimer = ThreadingHelper.Timer(() => { try { RequestNews(); } catch (Exception ex) { ex.LogError(); } }).Interval(TimeSpan.Zero, TimeSpan.FromDays(1)); }
private void TryCreateTimer() { lock (_syncRoot) { if (_isFlushing || _flushTimer != null) { return; } _flushTimer = ThreadingHelper .Timer(() => CultureInfo.InvariantCulture.DoInCulture(OnFlush)) .Interval(_flushInterval); } }
/// <summary> /// Initializes a new instance of the <see cref="LogManager"/>. /// </summary> public LogManager() { ConfigManager.TryRegisterService(this); Sources = new LogSourceList(this) { Application, new UnhandledExceptionSource() }; _flushTimer = ThreadingHelper.Timer(Flush); FlushInterval = TimeSpan.FromMilliseconds(500); }
/// <summary> /// To start timer of getting from sent <paramref name="connector" /> of real time candles. /// </summary> /// <typeparam name="TConnector">The type of the connection implementing <see cref="IExternalCandleSource"/>.</typeparam> /// <param name="connector">The connection implementing <see cref="IExternalCandleSource"/>.</param> /// <param name="registeredSeries">All registered candles series.</param> /// <param name="offset">The time shift for the new request to obtain a new candle. It is needed for the server will have time to create data in its candles storage.</param> /// <param name="requestNewCandles">The handler getting new candles.</param> /// <param name="interval">The interval between data updates.</param> /// <returns>Created timer.</returns> public static Timer StartRealTime <TConnector>(this TConnector connector, CachedSynchronizedSet <CandleSeries> registeredSeries, TimeSpan offset, Action <CandleSeries, Range <DateTimeOffset> > requestNewCandles, TimeSpan interval) where TConnector : class, IConnector, IExternalCandleSource { if (connector == null) { throw new ArgumentNullException(nameof(connector)); } if (registeredSeries == null) { throw new ArgumentNullException(nameof(registeredSeries)); } if (requestNewCandles == null) { throw new ArgumentNullException(nameof(requestNewCandles)); } return(ThreadingHelper.Timer(() => { try { if (connector.ConnectionState != ConnectionStates.Connected) { return; } lock (registeredSeries.SyncRoot) { foreach (var series in registeredSeries.Cache) { var tf = (TimeSpan)series.Arg; var time = connector.CurrentTime; var bounds = tf.GetCandleBounds(time, series.Security.Board); var beginTime = (time - bounds.Min) < offset ? (bounds.Min - tf) : bounds.Min; var finishTime = bounds.Max; requestNewCandles(series, new Range <DateTimeOffset>(beginTime, finishTime)); } } } catch (Exception ex) { ex.LogError(); } }) .Interval(interval)); }
private void EnsureInit() { if (_refreshTimer != null) { return; } Refresh(); var subscriptions = Invoke(f => f.GetSubscriptions(SessionId, DateTime.MinValue)); foreach (var subscription in subscriptions) { _subscriptions.Add(subscription.Id, subscription); } _refreshTimer = ThreadingHelper .Timer(Refresh) .Interval(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)); }
public MainWindow() { InitializeComponent(); Title = Title.Put(LocalizedStrings.Str3200); Loaded += OnLoaded; _dataTimer = ThreadingHelper .Timer(OnDataTimer) .Interval(TimeSpan.FromMilliseconds(1)); Theme.SelectedIndex = 1; SeriesEditor.Settings = new CandleSeries { CandleType = typeof(TimeFrameCandle), Arg = TimeSpan.FromMinutes(1) }; }
private MemoryStatistics() { var lastTime = DateTime.Now; _timer = ThreadingHelper.Timer(() => { if (IsDisposed) { return; } if (DateTime.Now - lastTime < Interval) { return; } lastTime = DateTime.Now; this.AddInfoLog(ToString()); }).Interval(Interval); }
/// <summary> /// Initializes a new instance of the <see cref="SnapshotRegistry"/>. /// </summary> /// <param name="path">Path to storage.</param> public SnapshotRegistry(string path) { _path = path; var isFlushing = false; var flushLock = new SyncObject(); _timer = ThreadingHelper.Timer(() => { lock (flushLock) { if (isFlushing) { return; } isFlushing = true; } try { var errors = _snapshotStorages.CachedValues.SelectMany(s => s.FlushChanges()).ToArray(); if (errors.Length > 0) { throw new AggregateException(errors); } } catch (Exception ex) { ex.LogError(); } lock (flushLock) { isFlushing = false; } }).Interval(TimeSpan.FromSeconds(10)); }
public SecuritiesWindow() { Securities = new ObservableCollection <Security>(); InitializeComponent(); _timer = ThreadingHelper.Timer(() => _quotesWindows.SyncDo(d => { foreach (var p in d) { var pair = p; var wnd = pair.Value; wnd.GuiAsync(() => { wnd.Quotes.Clear(); wnd.Quotes.AddRange(MainWindow.Instance.Trader.GetMarketDepth(pair.Key).Select(q => new SampleQuote(q))); }); } })) .Interval(TimeSpan.FromSeconds(1)); }
private Tuple <Guid, long> HandleResponse(ProductInfoMessage product, Tuple <Guid, long> tuple) { if (tuple is null) { throw new ArgumentNullException(nameof(tuple)); } tuple.Item1.ToErrorCode().ThrowIfError(); _sessionId = tuple.Item1; UserId = tuple.Item2; if (product != null) { _pingTimer = ThreadingHelper.Timer(() => { try { var session = _sessionId; if (session == null) { return; } lock (_pingSync) { Invoke(f => f.Ping(session.Value)); } } catch (Exception ex) { ex.LogError(); } }).Interval(TimeSpan.FromMinutes(10)); } return(tuple); }
public MainWindow() { InitializeComponent(); Title = Title.Put(LocalizedStrings.Str3200); Loaded += OnLoaded; _dataTimer = ThreadingHelper .Timer(OnDataTimer) .Interval(TimeSpan.FromMilliseconds(1)); SeriesEditor.Settings = new CandleSeries { CandleType = typeof(TimeFrameCandle), Arg = TimeSpan.FromMinutes(1) }; ConfigManager.RegisterService <ISubscriptionProvider>(_testProvider); ConfigManager.RegisterService <ISecurityProvider>(_securityProvider); ThemeExtensions.ApplyDefaultTheme(); }
/// <summary> /// Create a new activity session. /// </summary> /// <param name="product">Product type.</param> public void CreateSession(Products product) { if (_sessionId != 0) { throw new InvalidOperationException(); } var sessionId = AuthenticationClient.Instance.TryGetSession ?? Guid.Empty; #if DEBUG _sessionId = DateTime.Now.Ticks + sessionId.GetHashCode(); #else _sessionId = Invoke(f => f.CreateSession(product, sessionId)); #endif _pingTimer = ThreadingHelper.Timer(() => { try { lock (_pingSync) { #if !DEBUG if (_sessionId == 0) { return; } Invoke(f => f.Ping(_sessionId)); #endif } } catch (Exception ex) { ex.LogError(); } }).Interval(TimeSpan.FromMinutes(10)); }
internal void TryCreateTimer() { lock (_syncRoot) { if (_isFlushing || _flushTimer != null) { return; } _flushTimer = ThreadingHelper .Timer(() => { try { CultureInfo.InvariantCulture.DoInCulture(OnFlush); } catch (Exception ex) { ex.LogError("Flush CSV entity registry error: {0}"); } }) .Interval(_flushInterval); } }
private void AdapterOnNewOutMessage(Message message) { switch (message.Type) { case MessageTypes.Connect: { if (((ConnectMessage)message).Error == null) { lock (_timeSync) _prevState = _currState = ConnectionStates.Connected; // heart beat is disabled if (_adapter.HeartbeatInterval == TimeSpan.Zero) { break; } lock (_timeSync) { _canSendTime = true; _heartBeatTimer = ThreadingHelper.Timer(OnHeartbeatTimer).Interval(_adapter.HeartbeatInterval); } } else { lock (_timeSync) _prevState = _currState = ConnectionStates.Failed; } break; } case MessageTypes.Disconnect: { lock (_timeSync) { _prevState = _currState = ConnectionStates.Disconnected; if (_heartBeatTimer != null) { _heartBeatTimer.Dispose(); _heartBeatTimer = null; } } break; } case MessageTypes.Time: { if (message == _timeMessage) { lock (_timeSync) _canSendTime = true; return; } break; } } _newOutMessage.SafeInvoke(message); }
void ISnapshotStorage.Init() { if (!Directory.Exists(_path)) { Directory.CreateDirectory(_path); } var fileName = Path.Combine(_path, _serializer.FileName); byte[] buffer; Version version; if (File.Exists(fileName)) { using (var stream = File.OpenRead(fileName)) { version = new Version(stream.ReadByte(), stream.ReadByte()); buffer = new byte[_serializer.GetSnapshotSize(version)]; while (stream.Position < stream.Length) { stream.ReadBytes(buffer, buffer.Length); var message = _serializer.Deserialize(version, buffer); _snapshots.Add(_serializer.GetSecurityId(message), Tuple.Create(stream.Position - buffer.Length, message)); } _maxOffset = stream.Position; } } else { version = _serializer.Version; _maxOffset = 2; // version bytes buffer = new byte[_serializer.GetSnapshotSize(version)]; } _snapshotSize = buffer.Length; var isFlushing = false; ThreadingHelper.Timer(() => { Tuple <long, TMessage>[] changed; lock (_snapshots.SyncRoot) { if (_dirtySecurities.Count == 0) { return; } if (isFlushing) { return; } isFlushing = true; changed = _dirtySecurities.Select(id => { var tuple = _snapshots[id]; return(Tuple.Create(tuple.Item1, (TMessage)tuple.Item2.Clone())); }).OrderBy(t => t.Item1).ToArray(); _dirtySecurities.Count = 0; } try { using (var stream = File.OpenWrite(fileName)) { if (stream.Length == 0) { stream.WriteByte((byte)version.Major); stream.WriteByte((byte)version.Minor); } foreach (var tuple in changed) { stream.Seek(tuple.Item1, SeekOrigin.Begin); Array.Clear(buffer, 0, buffer.Length); _serializer.Serialize(version, tuple.Item2, buffer); stream.Write(buffer, 0, buffer.Length); } } } catch (Exception ex) { ex.LogError(); } lock (_snapshots.SyncRoot) isFlushing = false; }).Interval(TimeSpan.FromSeconds(10)); }
/// <summary> /// Initializes a new instance of the <see cref="StorageMessageAdapter"/>. /// </summary> /// <param name="innerAdapter">The adapter, to which messages will be directed.</param> /// <param name="entityRegistry">The storage of trade objects.</param> /// <param name="storageRegistry">The storage of market data.</param> public StorageMessageAdapter(IMessageAdapter innerAdapter, IEntityRegistry entityRegistry, IStorageRegistry storageRegistry) : base(innerAdapter) { if (entityRegistry == null) { throw new ArgumentNullException(nameof(entityRegistry)); } if (storageRegistry == null) { throw new ArgumentNullException(nameof(storageRegistry)); } _entityRegistry = entityRegistry; _storageRegistry = storageRegistry; Drive = _storageRegistry.DefaultDrive; var isProcessing = false; var sync = new SyncObject(); ThreadingHelper.Timer(() => { lock (sync) { if (isProcessing) { return; } isProcessing = true; } try { foreach (var pair in GetTicks()) { GetStorage <ExecutionMessage>(pair.Key, ExecutionTypes.Tick).Save(pair.Value); } foreach (var pair in GetOrderLog()) { GetStorage <ExecutionMessage>(pair.Key, ExecutionTypes.OrderLog).Save(pair.Value); } foreach (var pair in GetTransactions()) { GetStorage <ExecutionMessage>(pair.Key, ExecutionTypes.Transaction).Save(pair.Value); } foreach (var pair in GetOrderBooks()) { GetStorage(pair.Key, typeof(QuoteChangeMessage), null).Save(pair.Value); } foreach (var pair in GetLevel1()) { GetStorage(pair.Key, typeof(Level1ChangeMessage), null).Save(pair.Value); } foreach (var pair in GetCandles()) { GetStorage(pair.Key.Item1, pair.Key.Item2, pair.Key.Item3).Save(pair.Value); } foreach (var pair in GetPositionChanges()) { GetStorage(pair.Key, typeof(PositionChangeMessage), null).Save(pair.Value); } var news = GetNews().ToArray(); if (news.Length > 0) { _storageRegistry.GetNewsMessageStorage(Drive, Format).Save(news); } } catch (Exception excp) { excp.LogError(); } finally { lock (sync) isProcessing = false; } }).Interval(TimeSpan.FromSeconds(10)); }
private void StartTimer() { if (_timer != null) { return; } var period = ReConnectionSettings.Interval; var needHeartbeat = HeartbeatInterval != TimeSpan.Zero; var time = TimeHelper.Now; var lastHeartBeatTime = TimeHelper.Now; var sync = new SyncObject(); var isProcessing = false; if (needHeartbeat) { _canSendTime = true; period = period.Min(HeartbeatInterval); } var outMsgIntervalInitial = TimeSpan.FromSeconds(5); var outMsgInterval = outMsgIntervalInitial; _timer = ThreadingHelper .Timer(() => { lock (sync) { if (isProcessing) { return; } isProcessing = true; } try { var now = TimeHelper.Now; var diff = now - time; if (needHeartbeat && now - lastHeartBeatTime >= HeartbeatInterval) { ProcessHeartbeat(); lastHeartBeatTime = now; } ProcessReconnection(diff); outMsgInterval -= diff; if (outMsgInterval <= TimeSpan.Zero) { outMsgInterval = outMsgIntervalInitial; RaiseNewOutMessage(new TimeMessage { LocalTime = CurrentTime }); } time = now; } catch (Exception ex) { ex.LogError(); } finally { lock (sync) isProcessing = false; } }) .Interval(period); }