protected override void OnStart(string[] args)
        {
            this.WriteLog(USLogLevel.Debug, "USExWinService: Инициализирован старт сервиса");
            try
            {
                // создаем и запускаем WCF-сервис
                
                // задаем адрес хоста из прараметров
                Uri lServiceHostAddress = new Uri(Properties.Settings.Default.ServiceHostAddress);
                // задаем адрес конечной точки из параметров
                string lServiceEndPointAddress = Properties.Settings.Default.ServiceEndPointAddress;
                this.WriteLog(USLogLevel.Trace, "USExWinService: lServiceHostAddress = {0}; lServiceEndPointAddress = {1}", lServiceHostAddress, lServiceEndPointAddress);

                // создаем хост
                _host = new ServiceHost(typeof(USExService), lServiceHostAddress);
                this.WriteLog(USLogLevel.Trace, "USExWinService: ServiceHost created");

                var lBinding =new TcpChunkingBinding();
                lBinding.OpenTimeout = Properties.Settings.Default.OpenTimeout;
                lBinding.ReceiveTimeout = Properties.Settings.Default.ReceiveTimeout;
                lBinding.SendTimeout = Properties.Settings.Default.SendTimeout;
                lBinding.CloseTimeout = Properties.Settings.Default.CloseTimeout;

                this.WriteLog(USLogLevel.Trace, "lBinding params lBinding.OpenTimeout = {0}; lBinding.ReceiveTimeout = {1}; lBinding.SendTimeout = {2}; lBinding.CloseTimeout = {3}", lBinding.OpenTimeout, lBinding.ReceiveTimeout, lBinding.SendTimeout, lBinding.CloseTimeout);
                
                // добавляем точку доступа
                _host.AddServiceEndpoint(typeof(IUSExService), lBinding, lServiceEndPointAddress);
                this.WriteLog(USLogLevel.Trace, "USExWinService: Service End Point created");
                
                var lBehavior = _host.Description.Behaviors.Find<ServiceDebugBehavior>();
                if (lBehavior != null)
                {
                    lBehavior.IncludeExceptionDetailInFaults = true;
                    this.WriteLog(USLogLevel.Trace, "USExWinService: Задано ServiceDebugBehavior.IncludeExceptionDetailInFaults = True");
                }
                else
                {
                    this.WriteLog(USLogLevel.Debug, "USExWinService: ServiceDebugBehavior не определен");
                }
                
                // добавляем mex точку доступа
                this.WriteLog(USLogLevel.Trace, "USExWinService: Создаем MEX точку доступа");
                _host.Description.Behaviors.Add(new ServiceMetadataBehavior());
                this.WriteLog(USLogLevel.Trace, "USExWinService: MEX ServiceMetadataBehavior added");
                var mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();
                this.WriteLog(USLogLevel.Trace, "USExWinService: MEX TcpBinding added");
                _host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "MEX");
                this.WriteLog(USLogLevel.Trace, "USExWinService: MEX точка доступа создана");
                
                // открываем хост
                _host.Open();
                this.WriteLog(USLogLevel.Debug, "USExWinService: Сервис запущен успешно");
            }
            catch (Exception e)
            {
                this.WriteLogException(e.ToString(), e);
                throw;
            }
        }
        private string CallSyncService()
        {
            string lResult = string.Empty;

            if (mut.WaitOne(0))
            {
                try
                {
                    var lServiceHostAddress = new Uri(Properties.Settings.Default.ServiceHostAddress);
                    var lServiceEndPointAddress = Properties.Settings.Default.ServiceEndPointAddress;
                    var lEndPointAddress =
                        new EndpointAddress(new Uri(String.Format("{0}/{1}", lServiceHostAddress, lServiceEndPointAddress)));
                    this.WriteLog(USLogLevel.Trace, "SyncServiceProperties.CallSyncService: lEndPointAddress = {0}", lEndPointAddress);

                    var lBinding = new TcpChunkingBinding();
                    lBinding.OpenTimeout = Properties.Settings.Default.OpenTimeout;
                    lBinding.ReceiveTimeout = Properties.Settings.Default.ReceiveTimeout;
                    lBinding.SendTimeout = Properties.Settings.Default.SendTimeout;
                    lBinding.CloseTimeout = Properties.Settings.Default.CloseTimeout;

                    this.WriteLog(USLogLevel.Trace, "lBinding params lBinding.OpenTimeout = {0}; lBinding.ReceiveTimeout = {1}; lBinding.SendTimeout = {2}; lBinding.CloseTimeout = {3}", lBinding.OpenTimeout, lBinding.ReceiveTimeout, lBinding.SendTimeout, lBinding.CloseTimeout);

                    using (var factory = new ChannelFactory<IUSInService>(lBinding, lEndPointAddress))
                    {
                        try
                        {
                            this.WriteLog(USLogLevel.Trace, "SyncServiceProperties.CallSyncService: ChannelFactory created");
                            var service = factory.CreateChannel();
                            this.WriteLog(USLogLevel.Trace, "SyncServiceProperties.CallSyncService: IUSExService service = factory.CreateChannel created");
                            lResult = service.EntitySync(LinkSyncServiceEntitiesId);
                            this.WriteLog(USLogLevel.Trace, "SyncServiceProperties.CallSyncService: service.EntitySync выполнен");
                            factory.Close();
                        }
                        finally
                        {
                            factory.Abort();
                        }
                    }
                    this.WriteLog(USLogLevel.Trace, "SyncServiceProperties.CallSyncService: ChannelFactory Closed");
                }
                catch (Exception e)
                {
                    this.WriteLog(USLogLevel.Trace|USLogLevel.Debug, string.Format("SyncServiceProperties.CallSyncService: Ошибка синхронизации LinkSyncServiceEntitiesId = {0}. Ошибка: {1}", LinkSyncServiceEntitiesId, e));
                    this.WriteLogException(string.Format("SyncServiceProperties.CallSyncService: Ошибка синхронизации LinkSyncServiceEntitiesId = {0}. Ошибка: {1}", LinkSyncServiceEntitiesId, e), e);
                    lResult = string.Empty;
                }
                finally
                {
                    mut.ReleaseMutex();                    
                }
            }

            return lResult;
        }
        /// <summary>
        /// Метод синхронизации
        /// </summary>
        /// <param name="aLinkSyncServiceEntitiesId"></param>
        /// <param name="aIsFullSync"></param>
        /// <returns></returns>
        public static string EntitySync(double aLinkSyncServiceEntitiesId, bool aIsFullSync = false)
        {
            var beginArgument = new SyncEventArgument {Exception = null, Result = aLinkSyncServiceEntitiesId};
            OnBeginSync(beginArgument);
            
            _logger.Trace("EntitySync: Начата синхронизация: {0}", aLinkSyncServiceEntitiesId);
            LinkSyncServEntId = aLinkSyncServiceEntitiesId;
            IsFullSync = aIsFullSync;
            var lResult = string.Empty;
            try
            {
                using (var lData = new SyncServicesEntities(GetConnectionString()))
                {
                    lData.Connection.Open();
                    try
                    {
                        var lSyncDateTime = lData.GET_SYSDATE();
                        _syncParams = lData.GetSyncServiceData(aLinkSyncServiceEntitiesId);
                        if (_syncParams == null)
                        {
                            var ex = new NullReferenceException(lResult);
                            OnEndSync(new SyncEventArgument{Exception =ex,Result = lResult});
                            return lResult;
                        }
                        var lIteratorNumber = 1;
                        var lErrorMsg = string.Empty;
                        var lJSonElements = string.Empty;
                        int lSyncResult;
                        do
                        {
                            switch (Convert.ToInt16(lData.GetLinkSyncServEntData(aLinkSyncServiceEntitiesId, lIteratorNumber, ref lJSonElements, ref lErrorMsg)))
                            {
                                case 0: // ошибка
                                    lSyncResult = 0;
                                    lResult = lErrorMsg;
                                    break;
                                case 1: // успешное получение данных. 
                                    lSyncResult = 1;
                                    if (lJSonElements != string.Empty)
                                    {
                                        // успешное получение данных. данные не пустые. запускаем синхронизацию
                                        // формируем данные для передачи на филиал
                                        var lInData = new USInServiceValues
                                                          {
                                                              EntityTypeId = _syncParams.ElsysTypeId,
                                                              JsonEntityData = Convert.ToString(lJSonElements)
                                                          };
                                        // серриализация данных для передачи на филиал
                                        var lJsonInData = JsonConvert.SerializeObject(lInData);
                                        _logger.Trace("EntitySync: Кодировка на клиенте {0}", Encoding.Default.EncodingName);
                                        // создаем поток который будет передан на филиал
                                        var DBEncoding = Encoding.GetEncoding(Properties.Settings.Default.DBEncodingName);
                                        var TransmissionEncoding = Encoding.GetEncoding(Properties.Settings.Default.TransmissionEncodingName);
                                        _logger.Trace("EntitySync: Кодировка на базе {0}", DBEncoding.EncodingName);
                                        _logger.Trace("EntitySync: Кодировка передачи {0}", TransmissionEncoding.EncodingName);
                                        using (var ms = new MemoryStream(Encoding.Convert(DBEncoding, TransmissionEncoding, DBEncoding.GetBytes(lJsonInData))))
                                        {
                                            var lBinding = new TcpChunkingBinding
                                                               {
                                                                   OpenTimeout = Properties.Settings.Default.OpenTimeout,
                                                                   ReceiveTimeout =
                                                                       Properties.Settings.Default.ReceiveTimeout,
                                                                   SendTimeout = Properties.Settings.Default.SendTimeout,
                                                                   CloseTimeout = Properties.Settings.Default.CloseTimeout
                                                               };

                                            var endPointAdress = _syncParams.EndPointAddress;
                                            //endPointAdress = string.Empty;
                                            using (var factory = new ChannelFactory<IUSExService>(lBinding, new EndpointAddress(endPointAdress)))
                                            {
                                                try
                                                {
                                                    var service = factory.CreateChannel();
                                                    var lRetValuesStr = service.EntitySync(ms);
                                                    factory.Close();
                                                    var lRetValues = JsonConvert.DeserializeObject<USInServiceRetValues>(lRetValuesStr);
                                                    lSyncResult = Convert.ToInt16(lRetValues.Result);
                                                    lResult = lRetValues.ErrorMessage;
                                                }
                                                catch (Exception e)
                                                {
                                                    lResult =
                                                        string.Format("EntitySync: Синхронизация LinkSyncServiceEntitiesId = {0} закончилась с ошибкой. Ошибка: {1}",
                                                                      aLinkSyncServiceEntitiesId, e);
                                                    OnErrorSync(new SyncEventArgument {Exception = e,Result = lResult});
                                                    continue;
                                                }
                                                factory.Abort();
                                            }
                                            ms.Close();
                                        }
                                    }
                                    break;
                                case 2: // ошибки не было но данные не были получены
                                    lSyncResult = 2;
                                    lResult = lErrorMsg;
                                    OnErrorSync(new SyncEventArgument {Exception = null,Result = lResult});
                                    continue;
                                    //break;
                                default: lSyncResult = 0;
                                    lResult = string.Format("EntitySync: Синхронизация LinkSyncServiceEntitiesId = {0} закончилась с ошибкой. Не прогнозируемый результат получения данных",
                                                            aLinkSyncServiceEntitiesId);
                                    OnErrorSync(new SyncEventArgument {Exception = null,Result = lResult});
                                    continue;
                                    //break;
                            }

                            lIteratorNumber += 1;
                        }
                        while ((lSyncResult == 1) && (lJSonElements != string.Empty));

                        switch (lSyncResult)
                        {
                            case 0:
                                var s0 = string.Format("Ошибка при синхронизация сущности EntitySync: aLinkSyncServiceEntitiesId = {0} Описание {1}; Сущность {2}: {3}; Филиал {4}; Ошибка {5}",
                                              aLinkSyncServiceEntitiesId, _syncParams.Description, _syncParams.ElsysTypeId,
                                              _syncParams.ElsysTypeName, _syncParams.BranchName, lResult);
                                OnEndSync(new SyncEventArgument {Exception = null,Result = s0});
                                break;
                            case 1:
                                lData.SET_LINK_SYNC_SERV_CALL_DATA(Convert.ToDecimal(LinkSyncServEntId), lSyncDateTime);

                                var s1 =string.Format("Успешная синхронизация сущности EntitySync: aLinkSyncServiceEntitiesId = {0} Описание {1}; Сущность {2}: {3}; Филиал {4}",
                                              aLinkSyncServiceEntitiesId, _syncParams.Description, _syncParams.ElsysTypeId,
                                              _syncParams.ElsysTypeName, _syncParams.BranchName);
                                OnEndSync(new SyncEventArgument {Exception = null,Result = s1});
                                break;
                            case 2:
                                var s2 = string.Format("Cинхронизация сущности EntitySync не завершена: aLinkSyncServiceEntitiesId = {0} Описание {1}; Сущность {2}: {3}; Филиал {4}. Причина {5}",
                                              aLinkSyncServiceEntitiesId, _syncParams.Description, _syncParams.ElsysTypeId,
                                              _syncParams.ElsysTypeName, _syncParams.BranchName, lResult);
                                OnEndSync(new SyncEventArgument {Exception = null,Result = s2});
                                lResult = string.Empty;
                                break;
                        }
                    }
                    finally
                    {
                        lData.Connection.Close();
                        lData.Dispose();
                    }
                }
            }
            catch (Exception e)
            {
                lResult =
                    string.Format("EntitySync: Синхронизация LinkSyncServiceEntitiesId = {0} закончилась с ошибкой. Ошибка: {1}",
                                  aLinkSyncServiceEntitiesId, e);
                
                OnErrorSync(new SyncEventArgument {Exception = e,Result = lResult});
            }
            OnEndSync(new SyncEventArgument {Exception = null,Result = aLinkSyncServiceEntitiesId});
            return lResult;
        }
        public string EntitySync(double aLinkSyncServiceEntitiesId, bool aIsFullSync = false)
        {
            this.WriteLog(USLogLevel.Trace | USLogLevel.Debug, "EntitySync: Начата синхронизация: {0}", aLinkSyncServiceEntitiesId);
            LinkSyncServEntId = aLinkSyncServiceEntitiesId;
            IsFullSync = aIsFullSync;
            string lResult = string.Empty;
            
            try
            {
                using (var lData = new SyncServicesEntities(GetConnectionString()))
                {
                    lData.Connection.Open();
                    try
                    {
                        var lSyncDateTime = lData.GET_SYSDATE();
                        _syncParams = lData.GetSyncServiceData(aLinkSyncServiceEntitiesId);

                        if (_syncParams == null)
                        {
                            lResult = string.Format("EntitySync: aLinkSyncServiceEntitiesId = {0} параметры синхронизации не определены", aLinkSyncServiceEntitiesId);
                            this.WriteLog(USLogLevel.Trace | USLogLevel.Debug, lResult);
                            return lResult;
                        }

                        this.WriteLog(USLogLevel.Trace | USLogLevel.Debug, "EntitySync: aLinkSyncServiceEntitiesId = {0} Описание {1}; Сущность {2}: {3}; Филиал {4}",
                                aLinkSyncServiceEntitiesId, _syncParams.Description, _syncParams.ElsysTypeId,
                                _syncParams.ElsysTypeName, _syncParams.BranchName);
                        int lIteratorNumber = 1;
                        var lErrorMsg = string.Empty;
                        var lJSonElements = string.Empty;
                        int lSyncResult = 0;

                        do
                        {
                            this.WriteLog(USLogLevel.Trace, "EntitySync: aLinkSyncServiceEntitiesId = {0} данные по сущности получены и сериализованы. Шаг {1}", aLinkSyncServiceEntitiesId, lIteratorNumber);
                            switch (Convert.ToInt16(lData.GetLinkSyncServEntData(aLinkSyncServiceEntitiesId, lIteratorNumber, ref lJSonElements, ref lErrorMsg)))
                            {
                                case 0: // ошибка
                                    lSyncResult = 0;
                                    lResult = lErrorMsg;
                                    break;
                                case 1: // успешное получение данных. 
                                    lSyncResult = 1;
                                    if (lJSonElements != string.Empty)
                                    {
                                        // успешное получение данных. данные не пустые. запускаем синхронизацию

                                        // формируем данные для передачи на филиал
                                        var lInData = new USInServiceValues
                                        {
                                            EntityTypeId = _syncParams.ElsysTypeId,
                                            JsonEntityData = Convert.ToString(lJSonElements)
                                        };

                                        // серриализация данных для передачи на филиал
                                        string lJsonInData = Newtonsoft.Json.JsonConvert.SerializeObject(lInData);
                                        if (Properties.Settings.Default.NeedLogSyncData)
                                        {
                                            this.WriteLog(USLogLevel.Trace, "EntitySync: aLinkSyncServiceEntitiesId = {0} lJsonInData сформирован = {1}", aLinkSyncServiceEntitiesId, lJsonInData);
                                        }
                                        lInData = null;

                                        this.WriteLog(USLogLevel.Trace, "EntitySync: Кодировка на клиенте {0}", Encoding.Default.EncodingName);
                                        // создаем поток который будет передан на филиал
                                        var DBEncoding = Encoding.GetEncoding(Properties.Settings.Default.DBEncodingName);
                                        var TransmissionEncoding = Encoding.GetEncoding(Properties.Settings.Default.TransmissionEncodingName);
                                        this.WriteLog(USLogLevel.Trace, "EntitySync: Кодировка на базе {0}", DBEncoding.EncodingName);
                                        this.WriteLog(USLogLevel.Trace, "EntitySync: Кодировка передачи {0}", TransmissionEncoding.EncodingName);

                                        using (var ms = new MemoryStream(Encoding.Convert(DBEncoding, TransmissionEncoding, DBEncoding.GetBytes(lJsonInData))))
                                        {
                                            this.WriteLog(USLogLevel.Trace, "EntitySync: aLinkSyncServiceEntitiesId = {0} MemoryStream создан", aLinkSyncServiceEntitiesId);
                                            lJsonInData = String.Empty;

                                            var lBinding = new TcpChunkingBinding();
                                            lBinding.OpenTimeout = Properties.Settings.Default.OpenTimeout;
                                            lBinding.ReceiveTimeout = Properties.Settings.Default.ReceiveTimeout;
                                            lBinding.SendTimeout = Properties.Settings.Default.SendTimeout;
                                            lBinding.CloseTimeout = Properties.Settings.Default.CloseTimeout;

                                            this.WriteLog(USLogLevel.Trace, "lBinding params lBinding.OpenTimeout = {0}; lBinding.ReceiveTimeout = {1}; lBinding.SendTimeout = {2}; lBinding.CloseTimeout = {3}", lBinding.OpenTimeout, lBinding.ReceiveTimeout, lBinding.SendTimeout, lBinding.CloseTimeout);

                                            using (var factory = new ChannelFactory<IUSExService>(lBinding, new EndpointAddress(_syncParams.EndPointAddress)))
                                            {
                                                try
                                                {
                                                    this.WriteLog(USLogLevel.Trace, "EntitySync: aLinkSyncServiceEntitiesId = {0} ChannelFactory created", aLinkSyncServiceEntitiesId);
                                                    IUSExService service = factory.CreateChannel();
                                                    this.WriteLog(USLogLevel.Trace, "EntitySync: aLinkSyncServiceEntitiesId = {0} IUSExService service = factory.CreateChannel created", aLinkSyncServiceEntitiesId);
                                                    
                                                    var lRetValuesStr = service.EntitySync(ms);

                                                    this.WriteLog(USLogLevel.Trace, "EntitySync: aLinkSyncServiceEntitiesId = {0} service.EntitySync выполнен", aLinkSyncServiceEntitiesId);
                                                    factory.Close();
                                                    this.WriteLog(USLogLevel.Trace, "EntitySync: aLinkSyncServiceEntitiesId = {0} ChannelFactory Closed", aLinkSyncServiceEntitiesId);

                                                    this.WriteLog(USLogLevel.Trace, "EntitySync: aLinkSyncServiceEntitiesId = {0} Returned Value Deserialized", aLinkSyncServiceEntitiesId);
                                                    var lRetValues = Newtonsoft.Json.JsonConvert.DeserializeObject<USInServiceRetValues>(lRetValuesStr);
                                                    lSyncResult = Convert.ToInt16(lRetValues.Result);
                                                    lResult = lRetValues.ErrorMessage;
                                                }
                                                catch (Exception e)
                                                {
                                                    lResult =
                                                        string.Format("EntitySync: Синхронизация LinkSyncServiceEntitiesId = {0} закончилась с ошибкой. Ошибка: {1}",
                                                                      aLinkSyncServiceEntitiesId, e);
                                                    this.WriteLog(USLogLevel.Trace | USLogLevel.Debug, lResult, e);
                                                    this.WriteLogException(lResult, e);
                                                }
                                                factory.Abort();
                                            }
                                        }
                                    }
                                    break;
                                case 2: // ошибки не было но данные не были получены
                                    lSyncResult = 2;
                                    lResult = lErrorMsg;
                                    break;
                                default: lSyncResult = 0;
                                    lResult = string.Format("EntitySync: Синхронизация LinkSyncServiceEntitiesId = {0} закончилась с ошибкой. Не прогнозируемый результат получения данных",
                                                              aLinkSyncServiceEntitiesId);
                                    break;
                            }

                            lIteratorNumber += 1;
                        }
                        while ((lSyncResult == 1) && (lJSonElements != string.Empty));

                        switch (lSyncResult)
                        {
                            case 0:
                                this.WriteLog(USLogLevel.Trace | USLogLevel.Debug | USLogLevel.Error, "Ошибка при синхронизация сущности EntitySync: aLinkSyncServiceEntitiesId = {0} Описание {1}; Сущность {2}: {3}; Филиал {4}; Ошибка {5}",
                                aLinkSyncServiceEntitiesId, _syncParams.Description, _syncParams.ElsysTypeId,
                                _syncParams.ElsysTypeName, _syncParams.BranchName, lResult);
                                break;
                            case 1: 
                                lData.SET_LINK_SYNC_SERV_CALL_DATA(Convert.ToDecimal(LinkSyncServEntId), lSyncDateTime);

                                this.WriteLog(USLogLevel.Trace | USLogLevel.Debug, "Успешная синхронизация сущности EntitySync: aLinkSyncServiceEntitiesId = {0} Описание {1}; Сущность {2}: {3}; Филиал {4}",
                                    aLinkSyncServiceEntitiesId, _syncParams.Description, _syncParams.ElsysTypeId,
                                    _syncParams.ElsysTypeName, _syncParams.BranchName);
                                break;
                            case 2:
                                this.WriteLog(USLogLevel.Trace | USLogLevel.Debug, "Cинхронизация сущности EntitySync не завершена: aLinkSyncServiceEntitiesId = {0} Описание {1}; Сущность {2}: {3}; Филиал {4}. Причина {5}",
                                    aLinkSyncServiceEntitiesId, _syncParams.Description, _syncParams.ElsysTypeId,
                                    _syncParams.ElsysTypeName, _syncParams.BranchName, lResult);
                                lResult = string.Empty;
                                break;
                            default:
                                break;
                        }
                    }
                    finally
                    {
                        lData.Connection.Close();
                        this.WriteLog(USLogLevel.Trace, "EntitySync: aLinkSyncServiceEntitiesId = {0} Соединение закрыто", aLinkSyncServiceEntitiesId);
                        lData.Dispose();
                        this.WriteLog(USLogLevel.Trace, "EntitySync: aLinkSyncServiceEntitiesId = {0} lData.Dispose done", aLinkSyncServiceEntitiesId);
                    }
                }
            }
            catch (Exception e)
            {
                lResult =
                    string.Format("EntitySync: Синхронизация LinkSyncServiceEntitiesId = {0} закончилась с ошибкой. Ошибка: {1}",
                                  aLinkSyncServiceEntitiesId, e);
                this.WriteLog(USLogLevel.Trace | USLogLevel.Debug, lResult, e);
                this.WriteLogException(lResult, e);
            }
            this.WriteLog(USLogLevel.Trace | USLogLevel.Debug, "EntitySync: Завершена синхронизация: {0}", aLinkSyncServiceEntitiesId);

            return lResult;
        }