Grpc System.ObjectDisposedException:已关闭安全句柄

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Grpc System.ObjectDisposedException:已关闭安全句柄相关的知识,希望对你有一定的参考价值。

使用Pub / Sub停止服务并在Google App Engine上运行时,会收到以下堆栈跟踪。

System.ObjectDisposedException: Safe handle has been closed
    at System.Runtime.InteropServices.SafeHandle.DangerousAddRef
    at System.StubHelpers.StubHelpers.SafeHandleAddRef
    at Grpc.Core.Internal.ChannelSafeHandle.CreateCall
    at Grpc.Core.Internal.AsyncCall`2.CreateNativeCall
    at Grpc.Core.Internal.AsyncCall`2.Initialize
    at Grpc.Core.Internal.AsyncCall`2.StartDuplexStreamingCall
    at Grpc.Core.Calls.AsyncDuplexStreamingCall[TRequest,TResponse]
    at Grpc.Core.DefaultCallInvoker.AsyncDuplexStreamingCall[TRequest,TResponse]
    at Grpc.Core.Internal.InterceptingCallInvoker.AsyncDuplexStreamingCall[TRequest,TResponse]
    at Google.Cloud.PubSub.V1.Subscriber.SubscriberClient.StreamingPull
    at Google.Api.Gax.Grpc.ApiBidirectionalStreamingCall.<>c__DisplayClass0_0`2.<Create>b__0
    at Google.Api.Gax.Grpc.ApiBidirectionalStreamingCall`2.Call
    at Google.Cloud.PubSub.V1.SubscriberServiceApiClientImpl.StreamingPull
    at Google.Cloud.PubSub.V1.SubscriberClientImpl.SingleChannel.<StartAsync>d__18.MoveNext

对于该项目,我们使用ASP.NET Core和this库来处理Pub / Sub通信。使用Pub / Sub模拟器在本地调试时不存在该问题。因此,我们假设它与App Engine逐步淘汰docker容器的方式有关?只捕获异常将不是一个令人满意的解决方案,因为我们冒着处理消息未被确认的风险。我们能否以任何方式解决这个问题,以便我们能够安全地停止服务?

提前致谢。

答案

我发现错误在我的代码中...我在ASP.NET Core中使用IHostedService并使用以下方法停止订阅者:

cancellationToken.Register(async () => { await subscriber.StopAsync(token) })

但是,这会触发并忘记,因此在将对象部署到服务提供者中之前不会等待客户端正常停止。由于我使用了Google.Cloud.Diagnostics.AspNetCore(在服务提供程序中注册并使用Grpc)来记录一些有用的调试语句,因此可以在最终使用之前进行处理。

以上是关于Grpc System.ObjectDisposedException:已关闭安全句柄的主要内容,如果未能解决你的问题,请参考以下文章

grpc入门 --- 1 grpc简介

对GRPC的通用封装

GRPC 浅析

半译两个gRPC的C#库:grpc-dotnet vs Grpc.Core

grpc/go 如何在 grpc.Dial 中设置 grpc.ssl_target_name_override

GRPC的理解