public async Task DispatchToActorAsync()

in src/Microsoft.ServiceFabric.Actors/Runtime/ActorManager.cs [167:265]


        public async Task<T> DispatchToActorAsync<T>(
            ActorId actorId,
            ActorMethodContext actorMethodContext,
            bool createIfRequired,
            Func<ActorBase, CancellationToken, Task<T>> actorFunc,
            string callContext,
            bool timerCall,
            CancellationToken cancellationToken)
        {
            this.ThrowIfClosed();

            ExceptionDispatchInfo exceptionInfo = null;
            Exception exception = null;
            var retval = default(T);

            // get activeActor from the activeActors table
            using (var actorUseScope = this.GetActor(actorId, createIfRequired, timerCall))
            {
                var actor = actorUseScope.Actor;

                // ***
                // START: CRITICAL CODE
                // ***

                // Emit diagnostic info - before acquiring actor lock
                var lockAcquireStartTime = this.DiagnosticsEventManager.AcquireActorLockStart(actor);
                DateTime? lockAcquireFinishTime = null;
                try
                {
                    await
                        actor.ConcurrencyLock.Acquire(
                            callContext,
                            async innerActor => await this.HandleDirtyStateAsync(innerActor),
                            cancellationToken);
                }
                catch
                {
                    // Emit diagnostic info - failed to acquire actor lock
                    this.DiagnosticsEventManager.AcquireActorLockFailed(actor);
                    throw;
                }

                // WARNING: DO NOT PUT ANY CODE BETWEEN CONCURRENCY LOCK ACQUIRE AND TRY
                // THE LOCK NEEDS TO BE RELEASED IF THERE IS ANY EXCEPTION
                try
                {
                    // Emit diagnostic info - after acquiring actor lock
                    lockAcquireFinishTime = this.DiagnosticsEventManager.AcquireActorLockFinish(
                        actor,
                        lockAcquireStartTime);

                    retval =
                        await
                            this.DispatchToActorConcurrencyLockHeldAsync<T>(
                                actorId,
                                actorMethodContext,
                                actor,
                                actorFunc,
                                callContext,
                                cancellationToken);
                }
                catch (Exception e)
                {
                    exception = e;
                    try
                    {
                        exceptionInfo = ExceptionDispatchInfo.Capture(e);
                    }
                    catch
                    {
                        // ignored
                    }
                }

                // WARNING: DO NOT PUT ANY CODE BELOW BEFORE THE LOCK IS RELEASED
                // BECAUSE WE ARE NOT INSIDE A TRY-CATCH BLOCK
                //
                // signal that current execution is finished on this actor
                // since there is no call pending or this was the first actor call in the callContext
                await actor.ConcurrencyLock.ReleaseContext(callContext);

                // Emit diagnostic info - after releasing actor lock
                this.DiagnosticsEventManager.ReleaseActorLock(lockAcquireFinishTime);

                // ***
                // END: CRITICAL CODE
                // ***
                if (exceptionInfo != null)
                {
                    exceptionInfo.Throw();
                }
                else if (exception != null)
                {
                    throw exception;
                }

                return retval;
            }
        }