public async Task DeleteActorAsync()

in src/Microsoft.ServiceFabric.Actors/Runtime/ActorManager.cs [475:627]


        public async Task DeleteActorAsync(string callContext, ActorId actorId, CancellationToken cancellationToken)
        {
            ExceptionDispatchInfo exceptionInfo = null;

            if (!this.HasRemindersLoaded)
            {
                throw new ReminderLoadInProgressException(string.Format(
                    CultureInfo.CurrentCulture,
                    SR.DeleteActorConflictWithLoadReminders,
                    actorId));
            }

            ActorTrace.Source.WriteInfoWithId(
                TraceType,
                this.traceId,
                "DeleteActorAsync: Delete call received for actor {0}",
                actorId);

            // Use ActorConcurrencyLock to synchronize with other actor calls.
            // If the Actor is active, its ActorConcurrencyLock is used for synchronization.
            // If the actor is inactive, a Dummy Actor instance is created and its ActorConcurrencyLock is used for synchronization.
            using (
                var actorUseScope = this.GetActor(
                    actorId: actorId,
                    createIfRequired: true,
                    timerCall: false,
                    createDummyActor: true))
            {
                var actor = actorUseScope.Actor;

                await
                    actor.ConcurrencyLock.Acquire(
                        callContext,
                        (async innerActor => await this.HandleDirtyStateAsync(innerActor)),
                        ActorReentrancyMode.Disallowed,
                        cancellationToken);

                ActorTrace.Source.WriteInfoWithId(
                    TraceType,
                    this.traceId,
                    "DeleteActorAsync: Acquired ReentrancyGuard for actor {0}.",
                    actorId);

                // If Actor is already marked for deletion by other delete call, do not try to delete it again.
                if (actor.MarkedForDeletion)
                {
                    ActorTrace.Source.WriteInfoWithId(
                        TraceType,
                        this.traceId,
                        "DeleteActorAsync: Actor {0} is already marked for deletion, returning without processing this delete call.",
                        actorId);
                }
                else
                {
                    try
                    {
                        this.ThrowIfClosed();
                        cancellationToken.ThrowIfCancellationRequested();
                        actor.MarkedForDeletion = true;

                        // Remove actor state(and reminders) first and then unregister reminders as RemoveActorState can throw
                        // and in this case reminders should not be unregistered.
                        ActorTrace.Source.WriteInfoWithId(
                            TraceType,
                            this.traceId,
                            "DeleteActorAsync: Removing actor state and reminders for Actor {0}.",
                            actor.Id);

                        await this.StateProvider.RemoveActorAsync(actorId, cancellationToken);

                        ActorTrace.Source.WriteInfoWithId(
                            TraceType,
                            this.traceId,
                            "DeleteActorAsync: Unregistering all reminders for Actor {0}.",
                            actor.Id);

                        if (this.remindersByActorId.TryGetValue(actorId, out var actorReminders))
                        {
                            var reminderNames = actorReminders.Values.Select(r => r.Name).ToList().AsReadOnly();

                            foreach (var reminderName in reminderNames)
                            {
                                await this.UnregisterReminderAsync(reminderName, actor.Id, false);
                            }
                        }

                        ActorTrace.Source.WriteInfoWithId(
                            TraceType,
                            this.traceId,
                            "DeleteActorAsync: Clearing event subscriptions for actor {0}.",
                            actorId);

                        await this.eventManager.ClearAllSubscriptions(actorId);
                    }
                    catch (Exception e)
                    {
                        ActorTrace.Source.WriteInfoWithId(
                            TraceType,
                            this.traceId,
                            "DeleteActorAsync: Removing state for actor {0} caused exception {1}, {2}.",
                            actorId,
                            e.Message,
                            e.StackTrace);

                        exceptionInfo = ExceptionDispatchInfo.Capture(e);
                    }

                    try
                    {
                        // deactivate must happen outside of above try catch to avoid scenarios
                        // in which Remove actor state and reminder from state provider throws.
                        if (this.activeActors.TryRemove(actorId, out var removedActor))
                        {
                            ActorTrace.Source.WriteInfoWithId(
                                TraceType,
                                this.traceId,
                                "DeleteActorAsync: Deactivating actor {0}",
                                actorId);

                            await this.DeactivateActorAsync(removedActor);

                            ActorTrace.Source.WriteInfoWithId(
                                TraceType,
                                this.traceId,
                                "DeleteActorAsync: Completed Deactivation of actor {0}",
                                actorId);
                        }
                    }
                    catch (Exception e)
                    {
                        // Catch exception as ReentrantGuard must be released.
                        ActorTrace.Source.WriteInfoWithId(
                            TraceType,
                            this.traceId,
                            "DeleteActorAsync: Deactivating actor {0} caused exception {1}, {2}.",
                            actorId,
                            e.Message,
                            e.StackTrace);

                        exceptionInfo = ExceptionDispatchInfo.Capture(e);
                    }
                }

                await actor.ConcurrencyLock.ReleaseContext(callContext);

                if (exceptionInfo != null)
                {
                    exceptionInfo.Throw();
                }

                return;
            }
        }