WCF导致的界面挂死问题的处理

312 阅读2分钟

界面挂死无法操作问题的处理

最近和同事处理了我们产品网络版的一个问题。记录一下。

问题描述

问题大概是这样:我们产品的网络版在控制某套设备时候界面会卡到没有任何反应。但是同样的设备在单机版软件下却没有任何问题。网络版和单机版的区别大概就是网络版下,控制机器的采集服务,控制数据保存的数据中心服务和客户的客户端分别部署在不同的电脑上,而单机版则都在一台主机上。

思路

根据现象大概有以下几种思路。

  1. 用procdump的-h参数可以捕获界面挂死 时候的dump,再用windbg分析就可以了。

  2. VS的性能分析工具,可以函数调用的时间。

  3. 多暂停下进程,根据经验看看调用栈。

处理的结果大概如下:

  1. 最后方案一完全失败了,procdump并没有捕获出来。大概是因为界面没有完全卡死。

  2. 这种方式尴尬在有时出问题时是在生产环境,如果需要重启,很可能就没法复现问题了。

  3. 最后靠这种方式解决了。wcf的阻塞调用栈太明显(明显吃过这个亏)。

问题的原因是我们在wcf的客户端里有个接口时用的是同步调用的,大概是这么写的;

public static GetXXXValue(string key)
{
    try
    {
     	if(proxyService != null)
        {
            return proxyService.GetXXXValue(key);
        }
    }
    catch(Exception e)
    {
        //handle exception
    }
}

如果是单机版,都是本地环路肯定没有问题,在网络版的情况下,测试在1s内对接口的调用就耗时0.7秒了,再加上界面逻辑的调用,自然界面就有问题。

解决方案

  1. 用有线,实际上我之前做PCR的项目上海康SDK明确要求必须用有线,无线网在TCP连接数/稳定性/网速上都不达标。

  2. 改用Async接口,主要是老代码太多,动起来太麻烦。

  3. WCF客户端做缓存,能处理的尽量在本地处理。最后同事使用的是这种方式。

总结

这种界面卡顿的问题。大概可以归因以下我知道的两点。(只是我知道的)

  • 主线程被阻塞太多了,像本例一样。
  • GC,实际上也是上面这条原因,因为GC时候会阻塞线程。