Esempio n. 1
0
        // 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
                }
            }
        }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
        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);
        }
Esempio n. 6
0
        // 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
            }
        }