TryReceiveRequest 被无限次调用

发布于 2024-08-01 17:19:55 字数 1264 浏览 11 评论 0原文

我构建了一个自定义绑定,以便能够从其他源接收 HTTP 消息。 然而,它还不是没有错误的。

我观察到,一旦处理第一个请求,我的服务就会将 CPU 使用率推至 100%,并且随着进来的请求越来越多,服务变得越来越慢。在将日志记录命令插入到每个单个请求中后,可以看到这种行为的原因。绑定的功能。

在第一个请求进入之前,一切正常:

ChannelListener: OnBeginAcceptChannel
ChannelListener: OnAcceptChannel

然后,第一条消息的处理完成:

Channel: static constructor
Channel: constructor
ChannelListener: OnEndAcceptChannel (completes)
ChannelListener: Uri get
ChannelListener: OnBeginAcceptChannel
ChannelListener: OnAcceptChannel
Channel: OnOpen
Channel: BeginTryReceiveRequest
Channel: TryReceiveRequest
Channel: WaitForRequest
Channel: ReceiveRequest
Context: constructor
Channel: EndTryReceiveRequest (completes)
Context: RequestMessage get
`Channel: BeginTryReceiveRequest`
Context: Reply noTimeout
Context: Reply
Context: Close noTimeout
`Channel: TryReceiveRequest`
`Channel: WaitForRequest`
`Channel: ReceiveRequest (hangs)`
`Channel: EndTryReceiveRequest (doesn't complete since receive hangs)`
`Channel: BeginTryReceiveRequest`
`and so on...`

通道实现 IReplyChannel 接口,因此应该只能获取请求、回复请求,然后关闭通道。 ServiceModel 不只是关闭通道,而是不断向已使用的通道发送 TryReceiveRequest 垃圾邮件,而不管过去已使用过该通道。

有什么方法可以正确解决这个问题吗? 为什么 ServiceModel 在关闭回复上下文后不关闭通道,尽管在使用通道后保持通道打开是没有用的?

I have built a custom binding for being able to receive HTTP messages from an additional source. However, it is not bug-free yet.

I've observed that my service pushes CPU usage up to 100 % as soon as the first request was processed and the service getting slower and slower the more requests came in. The reason for this behavior could be seen after inserting logging commands into every single function of the binding.

Until before the first request gets in, everything works fine:

ChannelListener: OnBeginAcceptChannel
ChannelListener: OnAcceptChannel

Then, processing of the first message is done:

Channel: static constructor
Channel: constructor
ChannelListener: OnEndAcceptChannel (completes)
ChannelListener: Uri get
ChannelListener: OnBeginAcceptChannel
ChannelListener: OnAcceptChannel
Channel: OnOpen
Channel: BeginTryReceiveRequest
Channel: TryReceiveRequest
Channel: WaitForRequest
Channel: ReceiveRequest
Context: constructor
Channel: EndTryReceiveRequest (completes)
Context: RequestMessage get
`Channel: BeginTryReceiveRequest`
Context: Reply noTimeout
Context: Reply
Context: Close noTimeout
`Channel: TryReceiveRequest`
`Channel: WaitForRequest`
`Channel: ReceiveRequest (hangs)`
`Channel: EndTryReceiveRequest (doesn't complete since receive hangs)`
`Channel: BeginTryReceiveRequest`
`and so on...`

The channel implements the IReplyChannel interface, so it should only be possible to get a request, reply it and then close the channel.
Instead of just closing the channel, the ServiceModel keeps spamming TryReceiveRequest on an already used channel regardless of the channel already being used in the past.

Is there some way to fix this properly? Why doesn't the ServiceModel close the channel after closing the reply context although it's useless to keep the channel open after it is consumed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

很酷不放纵 2024-08-08 17:19:55

所以,也许有人仍然需要解决这个问题。 在 BeginTryReceiveRequestEndTryReceiveRequest 处检查通道的 State 属性。

…………

public IAsyncResult BeginTryReceiveRequest(TimeSpan timeout, AsyncCallback callback, object state)
        {
            if (State == CommunicationState.Closed)
            {
                return null;
            }
            return new TryReceiveRequestAsyncResult(timeout, this, callback, state);
        }

public bool EndTryReceiveRequest(IAsyncResult result, out RequestContext context)
            {
                if (State == CommunicationState.Closed)
                {
                    context = null;
                    return false;
                }
                return TryReceiveRequestAsyncResult.End(result, out context, this);
            }

So, maybe someone still need resolving of this problem. Check the State property of channel at BeginTryReceiveRequest and EndTryReceiveRequest.

.....

public IAsyncResult BeginTryReceiveRequest(TimeSpan timeout, AsyncCallback callback, object state)
        {
            if (State == CommunicationState.Closed)
            {
                return null;
            }
            return new TryReceiveRequestAsyncResult(timeout, this, callback, state);
        }

.....

public bool EndTryReceiveRequest(IAsyncResult result, out RequestContext context)
            {
                if (State == CommunicationState.Closed)
                {
                    context = null;
                    return false;
                }
                return TryReceiveRequestAsyncResult.End(result, out context, this);
            }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文