WCF 异步死锁?

发布于 2024-11-15 13:57:43 字数 2128 浏览 4 评论 0原文

是否有人遇到过 WaitAny 调用返回有效句柄索引,但 Proxy.End 调用阻塞的情况?或者有任何建议或如何最好地调试它 - 尝试跟踪、性能计数器(检查最大百分比)、到处记录

测试场景:2 个异步。请求正在发出(完整实现还有更多内容),第一个 Proxy.End 调用成功返回,但后续阻塞。我检查了 WCF 跟踪,没有看到任何特别有趣的东西。请注意,它正在自我查询存在于同一进程以及远程计算机中的端点(= 2个异步请求)

据我所知,两个查询的调用都在服务实现端进行,但它只是阻塞在随后的结束通话中。不过,它似乎只需要一次调用即可工作,无论是将请求发送到远程计算机还是自身;所以这与多个查询或导致锁定的其他因素有关。

我尝试了不同的“concurrencymode”和“instancecontextmode”,但它似乎对结果没有任何影响。

这是用于解析句柄列表的内部代码的简化版本:

ValidationResults IValidationService.EndValidate()
    {
        var results = new ValidationResults();

        if (_asyncResults.RemainingWaitHandles == null)
        {
            results.ReturnCode = AsyncResultEnum.NoMoreRequests;
            return results;                
        }

        var waitArray = _asyncResults.RemainingWaitHandles.ToArray();
        if (waitArray.GetLength(0) > 0)
        {
            int handleIndex = WaitHandle.WaitAny(waitArray, _defaultTimeOut);
            if (handleIndex == WaitHandle.WaitTimeout)
            {
                // Timeout on signal for all handles occurred                    
                // Close proxies and return...
            }

            var asyncResult = _asyncResults.Results[handleIndex];



            results.Results = asyncResult.Proxy.EndServerValidateGroups(asyncResult.AsyncResult);

            asyncResult.Proxy.Close();
            _asyncResults.Results.RemoveAt(handleIndex);
            _asyncResults.RemainingWaitHandles.RemoveAt(handleIndex);

    results.ReturnCode = AsyncResultEnum.Success;
            return results;
        }

    results.ReturnCode = AsyncResultEnum.NoMoreRequests;
        return results;
    }

以及调用此代码的代码:

 validateResult = validationService.EndValidateSuppression();
 while (validateResult.ReturnCode == AsyncResultEnum.Success)
 {
       // Update progress step                        
       //duplexContextChannel.ValidateGroupCallback(progressInfo);

     validateResult = validationService.EndValidateSuppression();
 }

我已经注释掉了启动节点上的回调(仅供参考,它实际上是一个 3 层设置,但问题与此无关)第二层调用第三层 - 回调从第二层到第一层,在本测试中已被删除)。想法?

Has anyone run into a situation where a WaitAny call returns a valid handle index, but the Proxy.End call blocks? Or has any recommendations or how best to debug this - tried tracing, performance counters (to check the max percentages), logging everywhere

The test scenario: 2 async. requests are going out (there's a bit more to the full implementation), and the 1st Proxy.End call return successfully, but the subsequent blocks. I've check the WCF trace and don't see anything particularly interesting. NOTE that it is self querying an endpoint that exists in the same process as well as a remote machine (=2 async requests)

As far as I can see the call is going through on the service implementation side for both queries, but it just blocks on the subsequent end call. It seems to work with just a single call though, regardless of whether it is sending the request to a remote machine or to itself; so it something to do with the multiple queries or some other factor causing the lockup.

I've tried different "concurrencymode"s and "instancecontextmode"s but it doesn't seem to have any bearing on the result.

Here's a cut down version of the internal code for parsing the handle list:

ValidationResults IValidationService.EndValidate()
    {
        var results = new ValidationResults();

        if (_asyncResults.RemainingWaitHandles == null)
        {
            results.ReturnCode = AsyncResultEnum.NoMoreRequests;
            return results;                
        }

        var waitArray = _asyncResults.RemainingWaitHandles.ToArray();
        if (waitArray.GetLength(0) > 0)
        {
            int handleIndex = WaitHandle.WaitAny(waitArray, _defaultTimeOut);
            if (handleIndex == WaitHandle.WaitTimeout)
            {
                // Timeout on signal for all handles occurred                    
                // Close proxies and return...
            }

            var asyncResult = _asyncResults.Results[handleIndex];



            results.Results = asyncResult.Proxy.EndServerValidateGroups(asyncResult.AsyncResult);

            asyncResult.Proxy.Close();
            _asyncResults.Results.RemoveAt(handleIndex);
            _asyncResults.RemainingWaitHandles.RemoveAt(handleIndex);

    results.ReturnCode = AsyncResultEnum.Success;
            return results;
        }

    results.ReturnCode = AsyncResultEnum.NoMoreRequests;
        return results;
    }

and the code that calls this:

 validateResult = validationService.EndValidateSuppression();
 while (validateResult.ReturnCode == AsyncResultEnum.Success)
 {
       // Update progress step                        
       //duplexContextChannel.ValidateGroupCallback(progressInfo);

     validateResult = validationService.EndValidateSuppression();
 }

I've commented out the callbacks on the initiating node (FYI it's actually an 3-tier setup, but the problem is isolated to this 2nd tier calling the 3rd tier - the callbacks go from the 2nd tier to the 1st tier which have been removed in this test). Thoughts?

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

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

发布评论

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

评论(1

梦忆晨望 2024-11-22 13:57:43

坚持我在评论中留下的解决方案。只需避免将回调链接到具有不同目的地(即代理)的 aysnc 调用

Sticking to the solution I left in my comment. Simply avoid chaining a callback to an aysnc calls that have different destinations (i.e. proxies)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文