// TODO: Put strings into the resources. // void P_ScheduleNextSignal(TimeSpan period, CancellationToken ct) { TaskUtilities .Delay(duration: period, cancellationToken: ct) .ContinueWith( continuationAction: doSignal, continuationOptions: TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion); // void doSignal(Task locDelayTask) { if (!IsDisposeRequested) { Exception locSignalException = null; try { Signal(signalProps: new TriggerSignalProperties(trigger: this)); } catch (Exception locCaughtException) { locSignalException = locCaughtException; } // if (!IsDisposeRequested && !ct.IsCancellationRequested) { P_ScheduleNextSignal(period: P_SelectNextPeriod(), ct: ct); } // #if !DO_NOT_USE_EON_LOGGING_API if (!(locSignalException is null) && !(locSignalException is ObjectDisposedException && IsDisposeRequested)) { this .IssueError( message: $"Ошибка вызова процедуры перевода триггера в сигнальное состояние (метод '{nameof(Signal)}').", error: locSignalException, includeErrorInIssueFaultException: true, severityLevel: locSignalException.GetMostHighSeverityLevel(baseLevel: SeverityLevel.Medium)); } #endif } } }
public void Add(Notification notification) { RemoveGroup(notification.Group); collection.Add(notification); if (collection.Count >= MaxNotifications) { var activeNotifications = ActiveNotifications(); if (!activeNotifications.Any()) { var firstNonPersistantNotification = activeNotifications.FirstOrDefault(item => !item.IsPersistent); var firstPersistantNotification = activeNotifications.FirstOrDefault(item => item.IsPersistent); var toRemove = firstNonPersistantNotification ?? firstPersistantNotification; RemoveWithDelay(toRemove, RemovedBy.System); } } if (!notification.IsPersistent) { TaskUtilities .Delay(TimeSpan.FromSeconds(6)) .ContinueWith(() => RemoveWithDelay(notification, RemovedBy.System), taskScheduler); } }
private void RemoveWithDelay( IEnumerable <Notification> items, Action <Notification> onBeforeDelay, RemovedBy removedBy, int millisecondDelay) { foreach (var item in items) { onBeforeDelay(item); } TaskUtilities .Delay(millisecondDelay) .ContinueWith(() => { foreach (var item in items) { var removed = collection.Remove(item); if (removed) { OnRemoved(item, removedBy); } } }, taskScheduler); }
/// <inheritdoc /> protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (this.settings.MaximumNumberOfRetries == 0) { return(await base.SendAsync(request, cancellationToken).ConfigureAwait(false)); } HttpResponseMessage responseMessage = null; var numberOfAttempts = 0; var sent = false; while (!sent) { var waitFor = this.GetNextWaitInterval(numberOfAttempts); try { responseMessage = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); ThrowHttpRequestExceptionIfResponseCodeCanBeRetried(responseMessage); sent = true; } catch (TaskCanceledException) { numberOfAttempts++; if (numberOfAttempts > this.settings.MaximumNumberOfRetries) { throw new TimeoutException(); } // ReSharper disable once MethodSupportsCancellation, cancel will be indicated on the token await TaskUtilities.Delay(waitFor).ConfigureAwait(false); } catch (HttpRequestException) { numberOfAttempts++; if (numberOfAttempts > this.settings.MaximumNumberOfRetries) { throw; } await TaskUtilities.Delay(waitFor).ConfigureAwait(false); } } return(responseMessage); }
public void AttachToApplication(IApplication application) { //this.window = application.Window; var scheduler = TaskScheduler.FromCurrentSynchronizationContext(); TaskUtilities .Delay(50) .ContinueWith(() => { this.RestoreLocationAndSize(); //this.AttachTo(this.window); }, scheduler); }
// TODO: Add component info into log // /// <summary> /// Создает ZIP-архив файла <paramref name="sourceFile"/>, сохраняет его по пути <paramref name="archiveFile"/>. /// <para>При <paramref name="deleteSourceFileOnSuccess"/> = <see langword="true"/>, исходный файл удаляется.</para> /// </summary> /// <param name="sourceFile"> /// Файл-источник архивирования. /// <para>Не может быть <see langword="null"/>. Файл должен существовать.</para> /// </param> /// <param name="archiveFile"> /// Файл-приёмник архивирования. /// <para>Не может быть <see langword="null"/>.</para> /// </param> /// <param name="overwrite"> /// Флаг перезаписи файла-приемника <paramref name="archiveFile"/>, если такой существует. /// </param> /// <param name="deleteSourceFileOnSuccess"> /// Флаг удаления файла-источника при успешном архивировании (исключения при удалении не выбрасываются). /// </param> /// <param name="overrideSourceFileName"> /// Переопределяет имя исходного файла в ZIP-архиве. /// <para>Если не указано, то имя соответствует имени исходного файла <paramref name="sourceFile"/>.</para> /// </param> /// <param name="ctx"> /// Контекст выполнения операции. /// </param> public static async Task ZipArchiveFileAsync(FileInfo sourceFile, FileInfo archiveFile, bool deleteSourceFileOnSuccess, string overrideSourceFileName = default, bool overwrite = default, IContext ctx = default) { sourceFile.EnsureNotNull(nameof(sourceFile)); archiveFile.EnsureNotNull(nameof(archiveFile)); overrideSourceFileName.Arg(nameof(overrideSourceFileName)).EnsureNotEmpty(); // if (!sourceFile.Exists) { throw new FileNotFoundException(FormatXResource(typeof(FileNotFoundException), null, sourceFile.FullName)); } try { var ct = ctx.Ct(); FileStream sourceFileStream = default; try { var retryOpen = true; for (; ;) { try { sourceFileStream = new FileStream(path: sourceFile.FullName, mode: FileMode.Open, access: FileAccess.Read, share: FileShare.Read); break; } catch (IOException ex) { if (retryOpen) { retryOpen = false; await TaskUtilities.Delay(duration : TimeoutDuration.FromMilliseconds(937), cancellationToken : ct, cancellationBreak : true).ConfigureAwait(false); continue; } else { throw new EonException(message: $"Ошибка при архивировании: файл-источник невозможно открыть для чтения.{Environment.NewLine}\tФайл:{sourceFile.FullName.FmtStr().GNLI2()}", innerException: ex); } } } archiveFile.Directory.Refresh(); if (!archiveFile.Directory.Exists) { archiveFile.Directory.Create(); } var archiveFileStream = default(FileStream); var zipArchive = default(ZipArchive); try { try { archiveFileStream = new FileStream(path: archiveFile.FullName, mode: overwrite ? FileMode.Create : FileMode.CreateNew, access: FileAccess.ReadWrite, share: FileShare.Read); } catch (Exception ex) { throw new EonException(message: $"Ошибка при архивировании: невозможно открыть поток для записи.{Environment.NewLine}\tФайл:{archiveFile.FullName.FmtStr().GNLI2()}", innerException: ex); } zipArchive = new ZipArchive(stream: archiveFileStream, mode: ZipArchiveMode.Create, leaveOpen: false, entryNameEncoding: Encoding.UTF8); var zipEntry = zipArchive.CreateEntry(entryName: overrideSourceFileName ?? sourceFile.Name, compressionLevel: CompressionLevel.Optimal); using (var zipEntryStream = zipEntry.Open()) { await sourceFileStream.CopyToAsync(destination : zipEntryStream, cancellationToken : ct).ConfigureAwait(false); await zipEntryStream.FlushAsync(cancellationToken : ct).ConfigureAwait(false); } } catch (Exception ex) { throw new EonException( message: $"Ошибка при архивировании.{Environment.NewLine}\tФайл-источник:{sourceFile.FullName.FmtStr().GNLI2()}{Environment.NewLine}\tФайл-приемник:{archiveFile.FullName.FmtStr().GNLI2()}", innerException: ex); } finally { zipArchive?.Dispose(); archiveFileStream?.Dispose(); } } finally { sourceFileStream?.Dispose(); } if (deleteSourceFileOnSuccess) { var retryDelete = true; for (; ;) { try { sourceFile.Delete(); break; } catch (IOException) { if (retryDelete) { retryDelete = false; await TaskUtilities.Delay(duration : TimeoutDuration.FromMilliseconds(937), cancellationToken : ct, cancellationBreak : true).ConfigureAwait(false); continue; } else { break; } } } } } catch (Exception exception) { throw new EonException( message: $"Ошибка при архивировании.{Environment.NewLine}\tФайл-источник:{sourceFile.FullName.FmtStr().GNLI2()}{Environment.NewLine}\tФайл-приемник:{archiveFile.FullName.FmtStr().GNLI2()}", innerException: exception); } }
// TODO: Put strings into the resources. // void P_HandleComponentActivationAttemptResult( RetrySettings retryOptions, IActivatableXAppScopeInstance component, int retryAttemptIndex, Task activationTask, XFullCorrelationId correlationId, CancellationToken ct) { // retryOptions = retryOptions.EnsureNotNull(nameof(retryOptions)).AsReadOnly().EnsureValid(); component.EnsureNotNull(nameof(component)); retryAttemptIndex.Arg(nameof(retryAttemptIndex)).EnsureNotLessThan(-1); activationTask.EnsureNotNull(nameof(activationTask)); // var logMessagePrologue = $"Отложенная активация. ИД корреляции: {correlationId.FmtStr().G()}."; if (activationTask.IsFaulted || activationTask.IsCanceled) { if (activationTask.IsCanceled) { #if !DO_NOT_USE_EON_LOGGING_API this .IssueWarning( messagePrologue: logMessagePrologue, message: $"Активация компонента была прервана или отменена.{Environment.NewLine}Повторная попытка не предусмотрена опциями активации компонента.{Environment.NewLine}\tКомпонент:{component.FmtStr().GNLI2()}", severityLevel: SeverityLevel.Medium); #endif } else { string retryActivationLogMessage; bool doRetryActivation; if (retryOptions.IsDisabled) { doRetryActivation = false; retryActivationLogMessage = $"Повторная попытка активации компонента запрещена настройками активации (см. '{nameof(RetrySettings)}.{nameof(RetrySettings.IsDisabled)}')."; } else if (retryOptions.MaxCount == -1) { doRetryActivation = true; retryActivationLogMessage = $"Повторная попытка активации компонента будет выполнена {(retryOptions.Interval == TimeoutDuration.Zero ? "немедленно" : $"через '{retryOptions.Interval.ToString()}'")}."; } else if (retryOptions.MaxCount == 0) { doRetryActivation = false; retryActivationLogMessage = $"Повторная попытка не предусмотрена настройками активации компонента (см. '{nameof(RetrySettings)}.{nameof(RetrySettings.MaxCount)}')."; } else if ((retryAttemptIndex + 1) < retryOptions.MaxCount) { doRetryActivation = true; retryActivationLogMessage = $"Повторная попытка активации компонента ({retryAttemptIndex + 2:d} из {retryOptions.MaxCount:d}) будет выполнена {(retryOptions.Interval == TimeoutDuration.Zero ? "немедленно" : $"через '{retryOptions.Interval.ToString()}'")}."; } else { doRetryActivation = false; retryActivationLogMessage = $"Повторной попытки активации компонента не будет, так как все попытки исчерпаны (кол-во попыток {retryOptions.MaxCount:d})."; } #if !DO_NOT_USE_EON_LOGGING_API this .IssueError( messagePrologue: logMessagePrologue, message: $"Ошибка активации компонента.{Environment.NewLine}{retryActivationLogMessage}{Environment.NewLine}\tКомпонент:{Environment.NewLine}{component.ToString().IndentLines2()}", error: activationTask.Exception, includeErrorInIssueFaultException: true, severityLevel: activationTask.Exception.GetMostHighSeverityLevel(baseLevel: SeverityLevel.Medium)); #endif // if (doRetryActivation) { if (retryOptions.Interval == TimeoutDuration.Zero) { P_StartComponentActivationAttempt(retryOptions: retryOptions, rethrowException: false, retryAttemptIndex: retryAttemptIndex + 1, correlationId: correlationId, ct: ct); } else { TaskUtilities .Delay(duration: retryOptions.Interval) .ContinueWith( continuationAction: locDelayTask => P_StartComponentActivationAttempt( retryOptions: retryOptions, rethrowException: false, retryAttemptIndex: retryAttemptIndex + 1, ct: ct, correlationId: correlationId), continuationOptions: TaskContinuationOptions.PreferFairness | TaskContinuationOptions.OnlyOnRanToCompletion, cancellationToken: ct, scheduler: TaskScheduler.Default); } } } } else { #if !DO_NOT_USE_EON_LOGGING_API this .IssueInformation( messagePrologue: logMessagePrologue, message: $"Активация компонента успешно выполнена.{Environment.NewLine}\tКомпонент:{component.FmtStr().GNLI2()}", severityLevel: SeverityLevel.Medium); #endif } }