【问题标题】:WCF webservice - is using lock going to cause problems?WCF webservice - 使用锁会导致问题吗?
【发布时间】:2013-10-09 03:05:33
【问题描述】:

我们有一个用于生成 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 的问题。这是关于在 Web 服务中使用 lock 的问题。请不要将标签更改为同步融合。

【问题讨论】:

  • 我不熟悉 Syncfusion - 是否可以创建对象的多个并发实例?我认为如果您有不同的实例,则不需要锁定。
  • 我也是这样,但这似乎是问题所在。也许他们在他们的代码中使用了一些静态的东西......

标签: c# multithreading wcf web-services locking


【解决方案1】:

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

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

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

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

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

.NET 4.0 提供了BlockingCollection 类来帮助解决这个问题。 (见this question

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

【讨论】:

  • 感谢您的回答,正是我正在寻找的那种信息。在我们的案例中,这个过程相当罕见,但这种饥饿仍然可能发生。我会考虑的。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 好吧,我们仍然很难从 Syncfusion 获得正常工作的版本,所以这不是真的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多