AilingRichMan AilingRichMan - 1 month ago 11
C# Question

Negative impacts to having a Static Context, ConcurrencyMode.Single, InstanceContextMode.PerSession in a WCF Service C#?

I have a WCF Service with a static data context, but no concurrency. It has been live for a year with no issues, but we saw some strange behavior the other day where users were passing data in correctly, but getting unexpected and incorrect data back. This does pass through an F5, so we're looking at issues there as well.

Would there be any negative impacts to having Single Concurrency Per Session as set-up below with a Static Context?

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.PerSession)]
public class AgencyUserManagementService : IAgencyUserManagement, IDisposable
{
private static UserDataContext _dataContext;

protected static UserDataContext Db
{
get { return _dataContext ?? (_dataContext = new UserDataContext()); }
}
}

public class UserDataContext : DbContext
{
public UserDataContext()
: base("Name=UserDataContext")
{
Database.SetInitializer<UserDataContext>(null);
}

public DbSet<TblAuthor> TblAuthors { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new TblAuthorMap());
}
}

Answer

Would there be any negative impacts to having Single Concurrency Per Session

The behaviour you will see for a service configured as such will be:

  • A service instance created per unique caller
  • Each service instance will queue concurrent requests (from the single caller) and process them one by one.

Negative impacts to having a Static Context

It follows then that a static variable defined in such a service will be accessed by the potentially multiple instances of the service.

If you have two concurrent users, then the single static DbContext is being used by both users at the same time.

This could very well lead to some weird problems, such as those you are seeing.

It's not recommended to use DbContext in the manner it is being used in your application for this reason (and others).

You should initialise a new DbContext for each service instance, which will mean the context will no longer be shared across callers. Many IOC containers provide plugins for WCF sessions which may help with this.

Sources:

Comments