/// <summary>
        ///     Unregisters an observer. This methods is invoked by an observer.
        /// </summary>
        /// <param name="topic">The topic.</param>
        /// <param name="entityId">The entity id of the observable.</param>
        /// This method is called by a management service or actor.
        /// <returns>The asynchronous result of the operation.</returns>
        public async Task UnregisterObserverActorAsync(string topic, EntityId entityId)
        {
            EntityId id = await this.GetEntityIdAsync();

            if (id == null)
            {
                return;
            }
            if (string.IsNullOrWhiteSpace(topic))
            {
                throw new ArgumentException($"The {nameof(topic)} parameter cannot be null.", nameof(topic));
            }
            if (entityId == null)
            {
                throw new ArgumentException($"The {nameof(entityId)} parameter cannot be null.", nameof(entityId));
            }
            for (int k = 1; k <= ConfigurationHelper.MaxQueryRetryCount; k++)
            {
                try
                {
                    ConditionalValue <Dictionary <Uri, EntityId> > topicState = await this.StateManager.TryGetStateAsync <Dictionary <Uri, EntityId> >(topic);

                    if (!topicState.HasValue)
                    {
                        ActorEventSource.Current.Message(
                            $"Observer not registered to the specified topic.\r\n[Observable]: {entityId}\r\n[Observer]: {id}\r\n[Publication]: Topic=[{topic}]");
                        return;
                    }
                    Dictionary <Uri, EntityId> observableDictionary = topicState.Value;
                    if (!observableDictionary.ContainsKey(entityId.EntityUri))
                    {
                        ActorEventSource.Current.Message(
                            $"Observer not registered to the specified observable.\r\n[Observable]: {entityId}\r\n[Observer]: {id}\r\n[Publication]: Topic=[{topic}]");
                        return;
                    }
                    if (entityId.Kind == EntityKind.Actor)
                    {
                        IServerObservableActor actorProxy = ActorProxy.Create <IServerObservableActor>(entityId.ActorId, entityId.ServiceUri);
                        await actorProxy.UnregisterObserverAsync(topic, id);
                    }
                    else
                    {
                        IServerObservableService serviceProxy = entityId.PartitionKey.HasValue
                            ? ServiceProxy.Create <IServerObservableService>(entityId.ServiceUri, new ServicePartitionKey(entityId.PartitionKey.Value))
                            : ServiceProxy.Create <IServerObservableService>(entityId.ServiceUri);
                        await serviceProxy.UnregisterObserverAsync(topic, id);
                    }
                    observableDictionary.Remove(entityId.EntityUri);
                    if (!observableDictionary.Any())
                    {
                        await this.StateManager.TryRemoveStateAsync(topic);
                    }
                    else
                    {
                        await this.StateManager.SetStateAsync(topic, observableDictionary);
                    }
                    ActorEventSource.Current.Message(
                        $"Observer successfully unregistered.\r\n[Observable]: {entityId}\r\n[Observer]: {id}\r\n[Subscription]: Topic=[{topic}]");
                    return;
                }
                catch (FabricTransientException ex)
                {
                    ActorEventSource.Current.Error(ex);
                }
                catch (AggregateException ex)
                {
                    foreach (Exception e in ex.InnerExceptions)
                    {
                        ActorEventSource.Current.Error(e);
                    }
                    throw;
                }
                catch (Exception ex)
                {
                    ActorEventSource.Current.Error(ex);
                    throw;
                }
                await Task.Delay(ConfigurationHelper.BackoffQueryDelay);
            }
            throw new TimeoutException(Constants.RetryTimeoutExhausted);
        }