8

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

问题是 3rd 方工具似乎存在多线程问题,并且在某些情况下同时对 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 服务中有这样的代码,它会导致任何问题吗?

笔记

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

4

3 回答 3

7

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

没有围绕锁的 FIFO 规则。因此,如果有连续负载,您可能会遇到这种情况:

  • 线程A声明锁
  • 线程B等待锁
  • 线程C等待锁
  • 线程A释放锁。锁是任意给线程的C
  • 线程D等待锁。现在你有线程B并且D都在等待。
  • 线程C释放锁。即使通过线程B已经等待最长时间,锁也被任意赋予线程D

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

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

.NET 4.0 提供了BlockingCollection帮助解决此问题的类。(见这个问题

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

于 2013-10-09T03:32:43.750 回答
4

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

如果不能启动多个 3rd 方组件实例,并且该组件不允许并发访问(最坏的情况),那么可以指定 InstanceContextMode = Single,ConcurrencyMode = Single;在这种情况下,WCF 只会实例化您的 WCF 对象的一个​​副本(我假设它是第 3 方组件的包装器),并且一次只处理一个请求。请求将被排队并以先进先出的方式处理。您不必在 wcf 服务中使用锁定,因为 WCF 运行时确保您可以同步访问 wcf 对象。

于 2013-10-14T18:36:53.987 回答
0

Essential PDF 是一个线程安全的组件,因此可以在多线程状态下创建 PDF 文档。您能否创建一个 Direct-trac 事件以获得解决方案。

于 2013-10-11T12:21:57.133 回答