WCF 网络服务 - 使用锁定会导致问题

本文关键字:问题 锁定 网络服务 WCF | 更新日期: 2023-09-27 18:34:34

我们有一个用于生成PDF文件的WCF Web服务操作。我们正在使用第三方工具来执行此操作(特别是Syncfusion(,我们目前可能无法替换它。

问题是,第三方工具似乎存在多线程问题,并且在某些情况下,当同时对Web服务进行多次调用时

,该工具不起作用。

我们可以通过使用lock并确保只有一个线程执行关键部分来解决问题:

Public Class GeneratorController
{
    // object we use for lock
    private static Object thisLock = new Object();
    public void Generate(ref PdfDocument pdfDocument)
    {
        lock (thisLock)
        {
             // critical section
        }
    }
}

我的问题是:这是一个好主意吗?如果我们在 Web 服务中有这样的代码,会导致任何问题吗?

注意

这不是关于同步的问题。这是关于在 Web 服务中使用lock的问题。请不要将标签更改为同步。

WCF 网络服务 - 使用锁定会导致问题

我在这里看到的问题是资源匮乏。

没有

关于锁的 FIFO 规则。因此,如果存在连续负载,则可以获得以下方案:

  • 线程 A 声明锁定
  • 线程B等待锁定
  • 线程C等待锁定
  • 线程A释放锁。锁被任意赋予线程C
  • 线程D等待锁定。现在您有线程BD都在等待。
  • 线程C释放锁。即使通过线程B等待的时间最长,锁也会任意交给线程D

因此,它一直持续到 WCF 调用超时,并且您会收到无法重现的错误。

如果我必须实现这一点,我将有一个专用于生成 PDF 文件的工作线程。此线程将在服务首次启动时启动,并等待从作业队列中选取作业。 每个 WCF 查询都会在此队列上放置一个请求,并且它会以某种方式阻止它,直到它知道作业已处理。

.NET 4.0 提供了BlockingCollection类来帮助解决此问题。(请参阅此问题(

这为您提供了没有完整解决方案的方法,因为它不是一个微不足道的问题。祝你好运!

WCF 支持同步调用服务对象,根据您的需要,您可能需要查看以下两个属性:

  • ServiceBehavior.InstanceContextMode:http://msdn.microsoft.com/en-us/library/system.servicemodel.servicebehaviorattribute.instancecontextmode.aspx
  • 服务行为.并发模式:http://msdn.microsoft.com/en-us/library/system.servicemodel.servicebehaviorattribute.concurrencymode.aspx

如果无法启动第三方组件的多个实例,并且该组件不允许并发访问(最坏情况(,则可以指定实例上下文模式 = 单个,并发模式 = 单个;在这种情况下,WCF 将仅实例化 WCF 对象的单个副本(我假设它是第三方组件的包装器(,并且一次只处理一个请求。请求将以FIFO方式排队和处理。您不必在 wcf 服务中使用锁,因为 WCF 运行时确保您已同步访问 wcf 对象。

基本 PDF 是一个线程安全组件,因此可以创建多线程状态的PDF文档。您能否创建一个直接跟踪事件以获得解决方案。