我有一个 WCF 双工服务(使用 net.tcp 绑定进行会话实例化),它可能会执行大量数据库访问。当它进入其高分贝访问例程时,它对任何 WCF 服务调用都没有响应。
我检查了 CPU 利用率,虽然很高,但不是 100%。这是在一个 4 芯盒子上。
WCF 似乎没有处理任何实际请求。不仅没有调用服务操作,而且我在 WCF 堆栈中还有一些安全自定义行为也没有被调用。这让我觉得 WCF 不知何故缺乏线程,因此无法分配新线程进行访问。
我不认为这是一个限制问题,因为我可以在该服务有几个当前会话(少于 5 个)时实现这一点。
有问题的数据库操作是数千个单行插入。这是通过每 500 次调用处理和重构的单个实体框架上下文来完成的,以减少实体框架内部缓存的内存积累。目标数据库是 SQL Express 2008 R2。
此服务中有相当数量的工作线程。所有这些都由任务并行库实例化......一些是常规的短期任务(使用 CLR 线程池),另一些是长时间运行的任务(获取自己的 CLR 线程),但这些都不是 I/O 线程(除非 CLR 正在做一些我不知道的魔法)。数据库写入发生在一个长时间运行的任务上。
是否有任何 WCF 或调试诊断工具可以报告或可视化 WCF 线程、工作线程、I/O 线程和 WCF 限制的当前状态?
环境总结
- WCF 服务托管在 Windows 服务中
- WCF 服务使用 net.tcp 双工绑定
- WCF 服务基于会话(双工合同要求)
- Windows 服务只有一个实例,但 WCF 服务对象的多个实例会根据 WCF 的要求进行实例化。
- WCF 服务操作快速将工作委派给在 Windows 服务中持久存在的后台线程。所有 WCF 操作都会快速返回,然后将后台线程生成的附加结果沿 WCF 双工回调通道传递。
- 所有数据库访问都是在后台工作线程上完成的。没有 WCF 线程用于长时间运行的工作。
- WCF 服务具有单一的自定义安全行为。没有其他行为(例如可靠的消息传递等)