views:

1035

answers:

4

We are developing a WCF based system. In the process we are trying to lock some data from being modified by more than one users. So we decided to have a data structure that will contain the necessary information for the locking logic to execute (by for example storing the ID of the locked objects)

The problem we are having is persisting that data between sessions. Is there anyway we can avoid executing expensive database calls? I am not sure how can we do that in WCF since it can only persist data (in memory) during an open session.

A: 

Perhaps a caching framework like velocity help you out.

Cristian Libardo
A: 

Create a second class and set its InstanceContextMode to single and move all the expensive methods there, then in your original class use that methods.

Mohammadreza
+1  A: 

Static members of the service implementing class are shared between sessions & calls.

Jimmy McNulty
+1  A: 

One option would be to use static members as Jimmy McNulty said. I have a WCF service that opens network connections based on a user-specified IP address. My service is configured for PerCall service instance mode. In each session, I check a static data structure to see if a network connection is already opened for the specified IP address. Here's an example.

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    void Start(IPAddress address);
}

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class MyService : IMyService
{
    private static readonly List<IPAddress> _addresses = new List<IPAddress>();
    public void Start(IPAddress address)
    {
        lock(((ICollection)_addresses).SyncRoot)
        {
            if (!_addresses.Contains(address)
            {
                // Open the connection here and then store the address.
                _addresses.Add(address);
            }
        }
    }
}

As configured, each call to Start() happens within its own service instance, and each instance has access to the static collection. Since each service instance operates within a separate thread, access to the collection must be synchonized.

As with all synchronization done in multithreaded programming, be sure to minimize the amount of time spent in the lock. In the example shown, once the first caller grabs the lock, all other callers must wait until the lock is released. This works in my situation, but may not work in yours.

Another option would be to use the Single service instance mode as opposed to the PerCall service instance mode.

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class MyService : IMyService
{ ... }

From everything I've read, though, the PerCall seems more flexible.

You can follow this link for differences between the two.

And don't forget that the class that implements your service is just that - a class. It works like all C# classes do. You can add a static constructor, properties, event handlers, implement additional interfaces, etc.

Matt Davis

related questions