Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 每次呼叫实例化的GRPC服务_C#_Grpc_Core - Fatal编程技术网

C# 每次呼叫实例化的GRPC服务

C# 每次呼叫实例化的GRPC服务,c#,grpc,core,C#,Grpc,Core,我已经在.NET core 3.1下创建了GRPC服务主机(使用中的GRPC.AspNetCore v2.30)。通过在“ProxyService”构造函数中放置一个断点,我可以看到每次调用都会实例化该类—每次来自客户端的GRPC调用都会命中断点。如何将其配置为始终使用相同的ProxyService实例 以下是程序和启动类: class Program { const int _port = 23456; static void Main(str

我已经在.NET core 3.1下创建了GRPC服务主机(使用中的GRPC.AspNetCore v2.30)。通过在“ProxyService”构造函数中放置一个断点,我可以看到每次调用都会实例化该类—每次来自客户端的GRPC调用都会命中断点。如何将其配置为始终使用相同的ProxyService实例

以下是程序和启动类:

    class Program
    {
        const int _port = 23456;

        static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
            Console.WriteLine("started - press any key to quit...");
            Console.ReadKey();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureKestrel(options =>
                    {
                        options.ConfigureEndpointDefaults(o =>
                        {
                            o.Protocols = HttpProtocols.Http2;
                            
                        });
                        options.ListenAnyIP(_port);
                    });
                    webBuilder.UseStartup<Startup>();
                });
    }

    public class ProxyService : StreamingApi.Protos.StreamingApi.StreamingApiBase
    {
        public ProxyService()
        {
    // gets here with every client call
        }

        public override Task<UpdateResponse> Update(UpdateRequest request, ServerCallContext context)
        {
            return Task.FromResult(new UpdateResponse());
        }
    }

   class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGrpc();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGrpcService<ProxyService>();
            });
        }
    }
类程序
{
const int_port=23456;
静态void Main(字符串[]参数)
{
CreateHostBuilder(args.Build().Run();
Console.WriteLine(“已启动-按任意键退出…”);
Console.ReadKey();
}
公共静态IHostBuilder CreateHostBuilder(字符串[]args)=>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder=>
{
webBuilder.ConfigureKestrel(选项=>
{
选项。配置端点默认值(o=>
{
o、 协议=HttpProtocols.Http2;
});
选项。ListenyIP(_端口);
});
webBuilder.UseStartup();
});
}
公共类代理服务:StreamingApi.Protos.StreamingApi.StreamingApiBase
{
公共代理服务()
{
//每次客户电话都会打过来
}
公共覆盖任务更新(UpdateRequest请求、ServerCallContext上下文)
{
返回Task.FromResult(newupdateResponse());
}
}
类启动
{
public void配置服务(IServiceCollection服务)
{
services.AddGrpc();
}
public void配置(IApplicationBuilder应用程序、IWebHostEnvironment环境)
{
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(端点=>
{
endpoints.MapGrpcService();
});
}
}

首先,让我猜猜您为什么要这样做:

  • ProxyService中有一些复杂的逻辑,比如某种初始化
  • 您有要在调用之间共享的静态变量
要解决第一种情况,您应使用以下任一方法:

    public ProxyService(IFooBar foobar)
    {
        this.foobar = foobar;
    }
    public override Task<UpdateResponse> Update(UpdateRequest request, ServerCallContext context)
    {
        await this.foobar.InitializeAsync();
        return Task.FromResult(new UpdateResponse());
    }
公共代理服务(IFooBar-foobar)
{
this.foobar=foobar;
}
公共覆盖任务更新(UpdateRequest请求、ServerCallContext上下文)
{
等待这个.foobar.InitializeAsync();
返回Task.FromResult(newupdateResponse());
}
或者系统中的其他触发器,例如“在服务启动时”:

公共接口iFooBarInitializer:IHostedService
{
}
公共级食品添加剂:IFOOBARINILIZER
{
公共异步任务StartAsync(CancellationToken令牌){等待this.foobar.InitializeAsync();}
}
//在您的配置中
public void配置服务(IServiceCollection服务)
{
services.AddGrpc();
services.AddSingleton();
services.AddHostedService(x=>x.GetService());
}
第二种情况更简单,因为您只需通过接口dpendency指定共享资源即可:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc();
        services.AddSingleton<IFooBarResource, FooBarResource>();
    }

    
public class ProxyService : StreamingApi.Protos.StreamingApi.StreamingApiBase
{
    public ProxyService(IFooBarResource myStaticResource)
    {
        this.myStaticResource = myStaticResource;
    }

    public override Task<UpdateResponse> Update(UpdateRequest request, ServerCallContext context)
    {
        var somethingGood = this.myStaticResource.GetMeSomethingGood();
        return Task.FromResult(new UpdateResponse());
    }
}
public void配置服务(IServiceCollection服务)
{
services.AddGrpc();
services.AddSingleton();
}
公共类代理服务:StreamingApi.Protos.StreamingApi.StreamingApiBase
{
公共代理服务(IFooBarResource myStaticResource)
{
this.myStaticResource=myStaticResource;
}
公共覆盖任务更新(UpdateRequest请求、ServerCallContext上下文)
{
var somethingGood=this.myStaticResource.GetMeSomethingGood();
返回Task.FromResult(newupdateResponse());
}
}

为什么要这样做?理想情况下,构造函数应该包含零成本逻辑,如依赖项链接。其他所有事情都应该在Update方法中发生,或者在服务启动之前发生。作为起点,我想测量处理的调用数,并每1秒将它们打印到控制台,因此我不能添加线程以保持恒定并在循环中这样做。可以配置吗?这是共享资源。您应该定义依赖接口,该接口将保存聚合值,并且是静态的。谢谢-看起来像我正在搜索的解决方案。仅供参考-是否有一种服务配置允许除WCF中的每次调用之外的其他服务实例化方法?我没有太多使用grpc,但您可以通过在IServiceCollection中指定生存期依赖项(每次调用、每次会话、每次数据库调用、当前日期时间中的偶数计数等)来实现这一点。由于在所有现代IDE中集成了自动模拟功能,这将变得容易得多。请阅读更多有关IoC和DI的信息,以便轻松管理您的业务实体的生命周期。谢谢-我实际上是指ProxyService本身,您没有注册。是的,我知道了,但遗憾的是没有找到任何快速参考,因此这可能意味着您应该通过DI来完成,至少它比某些属性驱动技术更简单。
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc();
        services.AddSingleton<IFooBarResource, FooBarResource>();
    }

    
public class ProxyService : StreamingApi.Protos.StreamingApi.StreamingApiBase
{
    public ProxyService(IFooBarResource myStaticResource)
    {
        this.myStaticResource = myStaticResource;
    }

    public override Task<UpdateResponse> Update(UpdateRequest request, ServerCallContext context)
    {
        var somethingGood = this.myStaticResource.GetMeSomethingGood();
        return Task.FromResult(new UpdateResponse());
    }
}