SPWeb/SPList thread safety

I recently came across a performance issue, which turned out to be related to a caching mechanism for an SPWeb. This worked on the development machine, but not on the production server. It turned out to be the lack of thread safety in the SPWeb object. The issue was that when querying a particular list (SPList) in the cached SPWeb, the SPListItemCollection returned from the query gave a NullReferenceException or ArgumentNullException, when trying to access any properties in the SPListItemCollection object.

This happened because it was another thread, which did the query, than the thread that created the SPWeb. So the solution had to be to recreate the SPWeb for every request. Unfortunately this performed very poor so we had to come up with another solution.

As a solution we created a dedicated thread (worker thread) within the IIS to manage the cached SPWeb, and all requesting threads from the IIS did the query through this worker thread. The advantage of this approach is, of course, that only one thread accessed the SPWeb, which could be cached during the lifetime of the IIS process. Hence improving the performance. The disadvantage is that the iis threads need to wait for the worker thread to be available to handle the query.

The solution is not trivial, as synchronization has to be carefully designed. The below diagram (a “Petri Net”) shows how this synchronization is designed in the solution, I used:

Sync designThe worker thread has a queue of objects holding information about the query (SPQuery) to perform. The same object can be populated with the result of the query by the worker thread, so the caller can use the result. When an IIS thread wants to perform a query, the thread queues an object on the queue and waits on a monitor (derived from the queue object) for a result. The worker thread is awakened (if it is in waiting mode) and performs the query on the cached SPWeb (created when the worker thread was started). When the result is ready the worker thread sets it on the query object and wakes the caller. Then the worker thread handles the next query or waits for one, if there is no queries to handle.

This solution works great and the performance is as expected. As mentioned the disadvantage is that this workerthread can be a bottleneck for the system, as a lot of IIS threads might wait for the workerthread. This is in particular a problem in a multiprocessor environment (our production system has 8 cores), as the solution does not utilize the multiple processors. An extension to the solution might be to use a pool of threads, which all hold a reference to the SPWeb. My solution works in our production environment without the extension, because the workerthread is not stressed that much. But I will consider to implement the extension in the future.

I will post code for my solution later.

One Response to “SPWeb/SPList thread safety”

  1. Hi

    I just created several SharePoint List Performance related blog entries at http://blog.dynatrace.com/category/net/sharepoint-net/.
    There is a lot of stuff going on under the hood depending on how you use the SharePoint object model. Understanding the internals should help to solve some performance related issues

    Regards
    Andi

Leave a Reply