protected override void Dispose(bool explicitDispose) { if (explicitDispose) { _appStartedSubscription?.Dispose(); _lastComponentActivation?.Dispose(); } _appStartedSubscription = null; _retryOptions = null; _lastComponentActivation = null; _activateControlFactory = null; // base.Dispose(explicitDispose); }
// TODO: Put strings into the resources. // void P_StartComponentActivationAttempt( RetrySettings retryOptions, bool rethrowException, int retryAttemptIndex, XFullCorrelationId correlationId, CancellationToken ct, Func <bool> breakCondition = default) { // retryOptions = retryOptions.EnsureNotNull(nameof(retryOptions)).AsReadOnly().EnsureValid(); // if (breakCondition is null) { breakCondition = () => ct.IsCancellationRequested || HasDeactivationRequested || !IsActive; } if (!breakCondition()) { var logMessagePrologue = $"Отложенная активация. ИД корреляции: {correlationId.FmtStr().G()}."; try { IActivatableXAppScopeInstance componentNewInstance = default; P_ComponentActivationAttempt newActivation = default; P_ComponentActivationAttempt existingActivation = default; for (; ;) { existingActivation = TryReadDA(ref _lastComponentActivation, considerDisposeRequest: true); if (existingActivation is null) { if (breakCondition()) { cleanup(ref componentNewInstance, ref newActivation); break; } else { newActivation = newActivation ?? new P_ComponentActivationAttempt( retryIndex: retryAttemptIndex, component: componentNewInstance = P_CreateComponent(), correlationId: correlationId, ct: ct); if (itrlck.UpdateBool(location: ref _lastComponentActivation, value: newActivation, comparand: existingActivation)) { if (breakCondition()) { itrlck.SetNullBool(location: ref _lastComponentActivation, comparand: newActivation); cleanup(ref componentNewInstance, ref newActivation); } break; } else { continue; } } } else { cleanup(ref componentNewInstance, ref newActivation); break; } } // if (!(newActivation is null)) { newActivation .ActivateControl .StartAsync() .ContinueWith( continuationAction: locTask => { var locCaughtException = default(Exception); try { if (locTask.IsCanceled || locTask.IsFaulted) { itrlck.SetNullBool(location: ref _lastComponentActivation, comparand: newActivation); } // P_HandleComponentActivationAttemptResult( retryOptions: retryOptions, component: componentNewInstance, retryAttemptIndex: newActivation.RetryAttemptIndex, activationTask: locTask, correlationId: correlationId, ct: ct); } catch (Exception locException) { locCaughtException = locException; throw; } finally { if (locTask.IsCanceled || locTask.IsFaulted) { try { cleanup(ref componentNewInstance, ref newActivation); } catch (Exception locException) { if (locCaughtException is null) { throw; } else { throw new AggregateException(locCaughtException, locException); } } } } }, continuationOptions: TaskContinuationOptions.PreferFairness); } } catch (Exception exception) { if (rethrowException) { throw new EonException(message: $"Ошибка запуска попытки активации.{Environment.NewLine}\tКомпонент:{this.FmtStr().GNLI2()}", innerException: exception); } else { #if !DO_NOT_USE_EON_LOGGING_API this .IssueError( messagePrologue: logMessagePrologue, message: "Ошибка запуска попытки активации.", error: exception, includeErrorInIssueFaultException: true, severityLevel: exception.GetMostHighSeverityLevel(baseLevel: SeverityLevel.Medium)); #endif } } } // void cleanup(ref IActivatableXAppScopeInstance locTarget, ref P_ComponentActivationAttempt locActivation) { var locCaughtExceptions = new List <Exception>(); try { locTarget?.Dispose(); locTarget = null; } catch (Exception locException) { locCaughtExceptions.Add(locException); } try { locActivation?.ActivateControl.StopAsync().WaitWithTimeout(); locActivation?.Dispose(); locActivation = null; } catch (Exception locException) { locCaughtExceptions.Add(locException); } if (locCaughtExceptions.Count > 0) { throw new AggregateException(innerExceptions: locCaughtExceptions); } } }