C# 如何使用服务远程处理处理不可用的服务

C# 如何使用服务远程处理处理不可用的服务,c#,azure-service-fabric,C#,Azure Service Fabric,我正在使用连接服务A和服务B。在部署时,我注意到服务A可以在服务B仍在启动时调用服务B中的方法。在这种情况下,AddStringToDictionary抛出一个NullReferenceException,因为尚未调用RunAsync public interface IServiceB : IService { Task AddStringToDictionary(string key, string value); } internal sealed class ServiceB

我正在使用连接服务A和服务B。在部署时,我注意到服务A可以在服务B仍在启动时调用服务B中的方法。在这种情况下,
AddStringToDictionary
抛出一个
NullReferenceException
,因为尚未调用
RunAsync

public interface IServiceB : IService
{
    Task AddStringToDictionary(string key, string value);
}

internal sealed class ServiceB : StatefulService, IServiceB
{
    private IReliableDictionary<string, string> myDictionary;

    public ServiceB(StatefulServiceContext context)
        : base(context)
    { 
        // StateMananger is null here.
    }

    public async Task AddStringToDictionary(string key, string value) 
    {
        using (var tx = StateManager.CreateTransaction())
        {
            // myDictionary is null if this is called before RunAsync.
            await this.myDictionary.SetAsync(tx, key, value);
            await tx.CommitAsync();
        }
    }

    protected override async Task RunAsync(CancellationToken cancellationToken) 
    {
        this.myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, string>>("myDictionary");
    }
}
我在
RunAsync
的末尾将此字段设置为
true
。然后,每个公共方法通过wifserviceunavailable()调用

目前,每次使用远程处理调用方法时,我都必须处理
ServiceUnavailableException
。我的问题是:有没有更好的方法来处理这种情况,或者这是一个好的解决方案?是否可以将我的自定义异常添加到
ServiceProxy
的临时异常以重试?

一种在初始化服务时阻止调用的实现。它使用
ManualResetEventSlim
来阻止。 它使用
信号量lim
强制对异步操作进行单线程访问

所有服务操作调用
等待WaitForInitializeAsync(CancellationToken.None)
该方法的实现是:

private async Task WaitForInitializeAsync(CancellationToken cancellationToken)
{
    if (_initializer.IsSet) return;
    await Task.Run(() => InitializeAsync(cancellationToken), cancellationToken);
   _initializer.Wait(cancellationToken);
}
InitializeAsync的实现:

private async Task InitializeAsync(CancellationToken cancellationToken)
{
   if (_initializer.IsSet) return;
   try
   {
      _semaphore.Wait(cancellationToken);
      if (_initializer.IsSet) return;
      [initializer logic here]
private async Task WaitForInitializeAsync(CancellationToken cancellationToken)
{
    if (_initializer.IsSet) return;
    await Task.Run(() => InitializeAsync(cancellationToken), cancellationToken);
   _initializer.Wait(cancellationToken);
}
private async Task InitializeAsync(CancellationToken cancellationToken)
{
   if (_initializer.IsSet) return;
   try
   {
      _semaphore.Wait(cancellationToken);
      if (_initializer.IsSet) return;
      [initializer logic here]