我们有一个用于生成 PDF 文件的 WCF Web 服务操作。我们正在使用第 3 方工具(特别是 Syncfusion)来执行此操作,目前我们可能无法替换它。
问题是第 3 方工具似乎在多线程方面存在问题,并且在某些情况下当同时多次调用 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。
最佳答案
我在这里看到的问题是资源匮乏。
没有关于锁的 FIFO 规则。因此,如果有持续负载,您可能会遇到这种情况:
- 线程
A
申请锁 - 线程
B
等待锁 - 线程
C
等待锁 - 线程
A
释放锁。锁任意给线程C
- 线程
D
等待锁。现在您有线程B
和D
都在等待。 - 线程
C
释放锁。即使线程B
等待的时间最长,锁也被任意给了线程D
。
它会一直持续到 WCF 调用超时,并且您会遇到无法重现的错误。
如果我必须实现它,我将有一个工作线程专用于生成 PDF 文件。该线程将在服务首次启动时启动,并等待从作业队列中取出作业。每个 WCF 查询都会在此队列上放置一个请求,在知道作业已处理之前,它可以通过某种方式进行阻塞。
.NET 4.0 提供了 BlockingCollection
类来帮助解决这个问题。 (参见 this question)
这为您提供了没有完整解决方案的方法,因为它不是一个微不足道的问题。祝你好运!
关于c# - WCF webservice - 使用锁会导致问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19262362/