Szymon
Szymon

Reputation: 43023

WCF webservice - is using lock going to cause problems?

We have a WCF web service operation that is used to generate PDF files. We're using a 3rd party tool to do that (Syncfusion specifically) which we may not be able to replace at the moment.

The problem is that it seems that 3rd party tool has a problem with multi-threading and doesn't work in some cases when there's multiple calls to the web service at the same time.

We can get rid of the problem by using lock and making sure that only one thread executes the critical section:

Public Class GeneratorController
{
    // object we use for lock
    private static Object thisLock = new Object();

    public void Generate(ref PdfDocument pdfDocument)
    {
        lock (thisLock)
        {
             // critical section
        }
    }
}

My questions is: is that a good idea? Is it going to cause any problems if we have a code like that in a web service?

Note

This is not a question about Syncfusion. This is a question about using lock in a web service. Do not change tags to syncfusion, please.

Upvotes: 8

Views: 4879

Answers (3)

X.J
X.J

Reputation: 662

WCF supports synchronized calling of your service objects, depending on your needs, you may want to look into the following two properties:

If you cannot launch multiple instances of 3rd party component, and the component does not allow concurrent acccess (the worst case), then you can specify InstanceContextMode = Single, and ConcurrencyMode = Single; In this case, WCF will only instantiate a single copy of your WCF object (which I assume is a wrapper around 3rd party component), and only one request is processed at a time. The requests will be queued up and processed in a FIFO manner. You don't have to use lock inside your wcf service, since the WCF runtime makes sure you have synchronized access to your wcf objects.

Upvotes: 4

George
George

Reputation: 71

Essential PDF is a thread safe component , so it is possible to create the PDF document in multi-threaded state. Can you please create a Direct-trac incident in order to get the solution.

Upvotes: 0

Andrew Shepherd
Andrew Shepherd

Reputation: 45272

The problem I see here is resource starvation.

There is no FIFO rule surrounding locks. So if there's a continuous load, you could get this scenario:

  • Thread A claims the lock
  • Thread B waits for the lock
  • Thread C waits for the lock
  • Thread A releases the lock. The lock is arbitrarily given to thread C
  • Thread D waits for the lock. Now you have thread B and D both waiting.
  • Thread C releases the lock. Even through thread B has been waiting the longest, the lock is arbitrarily given to thread D.

And so it continues until the WCF call times out, and you get an impossible-to-reproduce error.

If I had to implement this, I would have a single worker thread dedicated to generating the PDF files. This thread would be launched when the service first starts up, and it waits to pick up a job off a job queue. Each WCF query will place a request on this queue, and there will be some way it can block until it knows the job has been processed.

.NET 4.0 provides the BlockingCollection class to help with this. (See this question)

This gives you the approach without a complete solution because it isn't a trivial problem. Good luck!

Upvotes: 7

Related Questions