public void EstablishNewConnection() { Logg("EstablishNewConnection > Число подключений не считая этого = " + _connectionCounter.Count); lock (_connectionSyncObj) { if (!_isConnecting) { _isConnecting = true; } else { Logg("Подключение уже выполняется, отмена"); return; // уже идет подключение, другие попытки параллельного подключения отбрасываются } } try { Logg("Подключение..."); Socket localSocket; lock (_socketSyncObj) { if (_localUdpSocket == null) { _localUdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); _localUdpSocket.Bind(new IPEndPoint(IPAddress.Any, _localPort)); } localSocket = _localUdpSocket; } localSocket.BeginConnect(_targetEndpoint, ConnectCallback, localSocket); // Сокет передается, чтобы не заморачиваться с проверкой, тот ли это самый объект _connectionCounter.IncrementCount(); } catch (Exception ex) { Logg("Ошибка при установке подключения, исключение: " + ex); Socket localSocket; lock (_socketSyncObj) { localSocket = _localUdpSocket; } Disconnect(localSocket, ex); lock (_connectionSyncObj) { _isConnecting = false; } //EstablishNewConnection(); // Can rise stack overflow } }
private void AsyncRecurseArchiveReadMethod(string objName, WaitableCounter sharedTasksCounter) { Log.Log("Рекурсивное чтение архивов для " + objName); var nowTime = DateTime.Now; DateTime?timeToGet = _storage.GetFirstMissedTimeUpToTime(objName, nowTime); if (timeToGet.HasValue) { var time = timeToGet.Value; var cmd = new ReadArchiveRecordServiceCommand(time); Log.Log("Есть архивы, которые нужно вычитать. Имя объекта=" + objName + " Команда=<" + cmd.Comment + "> Время=" + cmd.RequestedTime.ToSimpleString() + " Арх.№=" + cmd.RecordNumber); sharedTasksCounter.IncrementCount(); _bumizIoManager.SendDataAsync(objName, cmd, result => { try { Log.Log("Асинхронный запрос к сети БУМИЗ выполнен для объекта " + objName); if (result != null) { if (result.ChannelException == null) { Log.Log(result.Bytes.ToText() + " <= для времени = " + time.ToSimpleString() + " Арх.№=" + cmd.RecordNumber); try { var ctResult = cmd.GetResult(result.Bytes); Log.Log(ctResult.ToString()); if (ctResult.RecordTime.Date == time.Date) { Log.Log("Даты совпадают, сохраняем данные в хранилище"); _storage.SaveData(objName, time, true, ctResult.Count1, ctResult.Count2, ctResult.Count3, ctResult.Status, ctResult.Xstatus); } else { throw new Exception("Дата внутри архива не совпадает с датой запроса"); } } catch (Exception ex) { Log.Log("Ошибка обработки ответа БУМИЗ, в хранилище будет записана информация о плохой записи архива"); Log.Log("Причина - исключение: " + ex.ToString()); _storage.SaveData(objName, time, false, 0, 0, 0, 0, 0); } finally { AsyncRecurseArchiveReadMethod(objName, sharedTasksCounter); } } else { Log.Log("Ошибка канала передачи данных: " + result.ChannelException.ToString()); Log.Log("Объект " + objName + " больше не будет опрашиваться в этой итерации (пока все остальные не закончат свои обмены)"); // Получается, что при ошибке передачи данных следующий запрос не будет осуществлен, и объект выпадает из цикла опроса, пока другие объекты не закончат свои работы } } else { Log.Log("Результат выполнения операции не существует, странно :О"); } } catch (Exception ex) { Log.Log("Произошла ошибка при разборе ответа от объекта " + objName); Log.Log(ex.ToString()); // TODO: что делать при ошибке чтения данных (нет связи с FRAM)? } finally { Log.Log("Декремент счетчика задач сети БУМИЗ для объекта " + objName); sharedTasksCounter.DecrementCount(); } }, IoPriority.Low); } else { Log.Log("Либо ошибка хранилища, либо для объекта " + objName + " все данные вычитаны"); } }