public RemoteScannerInterface( ILogger logger, CallPropertiesConfig commonCallProperties, CallPropertiesConfig synchronizationCallProperties, CallPropertiesConfig printingCallProperties) { CodeContract.Requires(logger != null); CodeContract.Requires(commonCallProperties != null); CodeContract.Requires(synchronizationCallProperties != null); CodeContract.Requires(printingCallProperties != null); _logger = logger; _commonCallProperties = commonCallProperties; _synchronizationCallProperties = synchronizationCallProperties; _printingCallProperties = printingCallProperties; }
private T SafeCall <T>(Func <T> method, CallPropertiesConfig callProps, T returnOnError) { if (!_alive) { return(returnOnError); } var tryCount = 0; var methodComplete = new AutoResetEvent(false); while (!_disposed && _alive) { try { var result = default(T); Exception methodEx = null; methodComplete.Reset(); var thread = ThreadUtils.StartBackgroundThread( () => { try { result = method(); } catch (Exception ex) { methodEx = ex; } finally { methodComplete.Set(); } }); if (!methodComplete.WaitOne(callProps.Timeout)) { thread.SafeAbort(); throw new TimeoutException("Не дождались завершение выполнения метода"); } if (methodEx != null) { throw methodEx; } return(result); } catch (Exception ex) { _logger.LogVerbose( Message.SyncCallRemoteMethodFailed, () => { var methodInfo = (new StackTrace()).GetFrame(3).GetMethod(); return(new object[] { methodInfo.Name, ex.ToString() }); }); if ( // ошибка не из-за сети ((!(ex is SocketException) && !(ex is RemotingException)) && !(ex is TimeoutException)) || ++tryCount >= callProps.MaxTryCount || !_alive || _disposed) { RaiseDisconnected(); return(returnOnError); } if (!Monitor.TryEnter(s_ifrestartSync)) { Thread.Sleep(300); _ifrestartDoneEvent.WaitOne(TimeSpan.FromMinutes(1)); continue; } try { _ifrestartDoneEvent.Reset(); IfrestartResult res; if (PlatformDetector.IsUnix) { _logger.LogVerbose(Message.SyncIfrestartStarting); string lastLine = null; ProcessHelper.StartProcessAndWaitForFinished( "./ifrestart.sh", string.Format("{0} {1}", callProps.RetryDelay, _remoteScannerInfo.IpAddress), state => { lastLine = state.Line; return(false); }, null); _logger.LogVerbose(Message.SyncIfrestartDone, lastLine); int i; res = int.TryParse(lastLine, out i) ? (IfrestartResult)i : IfrestartResult.Failed; } else { _logger.LogVerbose(Message.Common_Debug, "Имитируем выполнение команды переподнятия сети"); Thread.Sleep(4000 + callProps.RetryDelay * 2 * 1000); res = IfrestartResult.OkAfterRestart; } switch (res) { case IfrestartResult.OkAfterRestart: _logger.LogVerbose(Message.SyncTryCallRemoteMethodAgain, () => { var methodInfo = (new StackTrace()).GetFrame(3).GetMethod(); return(new object[] { methodInfo.Name, tryCount + 1 }); }); continue; default: RaiseDisconnected(); return(returnOnError); } } finally { Monitor.Exit(s_ifrestartSync); _ifrestartDoneEvent.Set(); } } } return(returnOnError); }