WCF Percall mode and threadstatic variables - c#

We have multiple WCF services all working with InstanceContextMode=PerCall and all WCF service instances are generated by employing Unity (IOC) and implementing IInstanceProvider.
A correlation identifier is used to audit all method calls and database processes with the same identifier.
In order to achieve this, an endpoint behavior is created by implementing IDispatchBehavior and in AfterReceiveRequest method, a guid is generated and assigned to a ThreadStatic (CommonData) property. This property can be access in all layers of the application. The following code block shows the population of CommonData, and the CommonData class;
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
CommonData.ClearDictionary();
//the lines between are deleted as they are not relevant to the question
CommonData.Current.Add(MessageHeaderCodes.CorrelationId, Guid.NewGuid().ToString());
return null;
}
and commondata class:
public class CommonData
{
[ThreadStatic]
private static Dictionary<string, string> headerData;
public static Dictionary<string, string> Current
{
get
{
if (headerData == null)
{
headerData = new Dictionary<string, string>();
}
return headerData;
}
}
private CommonData()
{
}
public static string GetHeader(string header)
{
string headerValue = string.Empty;
KeyValuePair<string, string> headerKeyValuePair = CommonData.Current.SingleOrDefault(p => p.Key == header);
headerValue = headerKeyValuePair.Value;
return headerValue;
}
public static void ClearDictionary()
{
Current.Clear();
}
}
The problem here is the following;
In some of the services, developers reported that the correlation identifier returns null. Since the problem is intermittant it is not possible to have a full stack trace at the moment. Also, they stated that reseting IIS resolves this problem temporarily.
Any help is appreciated...

This doesn't really answer your question, and would have been a comment, except I wanted to have some code...
I am confused by your GetHeader method. Why are you doing a Linq .FirstOrDefault() on the dictionary, instead of just:
public static string GetHeader(string header)
{
if(CommonData.Current.ContainsKey(header))
return CommonData.Current[header];
return null;
}
Aside from that, I don't actually see anything wrong with your code. I am curious as to where the developers are getting the null identifier. They would of course have to make sure they are on the same thread that the dispatcher was called on. If any async process, or ThreadPool was used anywhere to run something on another thread, then the [ThreadStatic] would not exist.
I had an issue once where I (very stupidly) referenced my [ThreadStatic] variable from a method that was called by a finalizer, which is run on the GC thread, so my thread static was always null. oops :)

As Blam suggested, I have employed OperationContext.Current by writing an Extension to store custom objects. Below is the extension:
public class OperationContextExtension : IExtension<OperationContext>
{
public void Attach(OperationContext owner)
{
this.Current = new Dictionary<string, string>();
}
public void Detach(OperationContext owner)
{
this.Current = null;
}
public Dictionary<string,string> Current { get; set; }
}
On the otherhand, I have to add System.ServiceModel reference to the domain objects. Although it does not seem to be a proper way as domain objects can access to the service layer, it resolved my problem.

Several things:
First, Your Threadstatic value creation is better implemented by ThreadLocal. This is basically the case whenever you need your threadstatic field to be initialized. Use
private static ThreadStatic<Dictionary<string, string>> headerData = new ThreadStatic<Dictionary<string, string>>(() => new Dictionary<string, string>());
Second, for acquiring the value from the dictionary, what you're looking for is the TryGetValue method. I.e. not Contains-Get pair (as it does hash lookup twice unnecessary), and certainly not SingleOrDefault.
And third, to have a reliable ID identifying whatever happened from the one service call, just have it as one of the parameters of all the subsequent method calls.

Related

Index was outside the bounds of the array C# (Catch and Con(c)(q)ure)

I have an error, some of the users have reported recently, but i couldn't catch.
According to research i think it can be solved with changing Dictionary to ConcurrentDictionary. The question is how can i catch the error? What is the best way to use ConcurrentDictionary for adding (TryAdd or AddorUpdate)?
Edit: codes in references.
private static Dictionary<string, SportsFacility> _selectedFacilities = new Dictionary<string, SportsFacility>();
public static SportsFacility SelectedFacility
{
get
{
return _selectedFacilities.ContainsKey(HttpContext.Current.Session.SessionID) ? _selectedFacilities[HttpContext.Current.Session.SessionID] : null;
}
set
{
if (_selectedFacilities.ContainsKey(HttpContext.Current.Session.SessionID))
{
_selectedFacilities[HttpContext.Current.Session.SessionID] = value;
}
else
{
_selectedFacilities.Add(HttpContext.Current.Session.SessionID, value);
}
}
}
Never minding the reason for working with the session id like this (there are certainly better ways of doing this), here is a slight improvement to your code:
private static readonly object _selectedFacilitiesLocker=new object();
private static Dictionary<string, SportsFacility> _selectedFacilities = new Dictionary<string, SportsFacility>();
private static bool TryGetSelectedFacility(string key, out SportsFacility facility)
{
// Since you are in a web environment and are using statics, you must lock this index whenever you use it
lock(_selectedFacilitiesLocker)
{
return _selectedFacilities.TryGetValue(key, out facility);
}
}
private static void UpdateSelectedFacility(string key, SportsFacility facility)
{
// Since you are in a web environment and are using statics, you must lock this index whenever you use it
lock(_selectedFacilitiesLocker)
{
_selectedFacilities[key] = facility;
}
}
public static SportsFacility SelectedFacility
{
get
{
SportsFacility facility;
if(!TryGetSelectedFacility(HttpContext.Current.Session.SessionID, out facility))
return null;
else
return facility;
}
set
{
UpdateSelectedFacility(HttpContext.Current.Session.SessionID, value);
}
}
Using a static index ("_selectedFacilities") like you do in your code spells trouble in a multi threaded environment, like a web server. If you want a design like this (without going into the reasons for why you shouldn't), you must add a lock around it whenever you use it. Otherwise you'll get all kinds of strange bugs as soon as you're in production. It may seem to work while you're happily testing yourself but life isn't that easy, unfortunately.
This exception caused by using dictionary object from multiple threads without syncronizing. You can solve it by syncronizing access to dictionary object with lock (as #KEkegren suggested) or with ReaderWriterLockSlim
In addition to syncronizing manually, as you said, you can use ConcurrentDictionary without using locks. It is supported on .NET Framework 4 and above.
All operations on ConcurrentDictionary are atomic, meaning all methods are thread safe and you do not need to syncronize access.
However you should not use the same way as Dictionary. I mean, you should not check for key existence and after that add a new value. Instead you should use AddOrUpdate in your case because it makes what you are trying to do in a single atomic operation.
Rather than criticizing a particular approach, provide an answer that shows a better solution.
This does the same thing you are doing with a static dictionary using session variables.
public static SportsFacility SelectedFacility
{
get
{
return (Session["SelectedFacility"] as SportsFacility);
}
set
{
Session["SelectedFacility"] = value;
}
}
Good luck!

Do replace operations on different ConcurrentDictionary keys share one lock?

Does replacing a value associated with a ConcurrentDictionary key lock any dictionary operations beyond that key?
EDIT: For example, I'd like to know if either thread will ever block the other, besides when the keys are first added, in the following:
public static class Test {
private static ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, int>();
public static Test() {
new Thread(UpdateItem1).Start();
new Thread(UpdateItem2).Start();
}
private static void UpdateItem1() {
while (true) cd[1] = 0;
}
private static void UpdateItem2() {
while (true) cd[2] = 0;
}
}
Initially I assumed it does, because for example dictionary[key] = value; could refer to a key that is not present yet. However, while working I realized that if an add is necessary it could occur after a separate lock escalation.
I was drafting the following class, but the indirection provided by the AccountCacheLock class is unnecessary if the answer to this question (above) is "no". In fact, all of my own lock management is pretty much unneeded.
// A flattened subset of repository user values that are referenced for every member page access
public class AccountCache {
// The AccountCacheLock wrapper allows the AccountCache item to be updated in a locally-confined account-specific lock.
// Otherwise, one of the following would be necessary:
// Replace a ConcurrentDictionary item, requiring a lock on the ConcurrentDictionary object (unless the ConcurrentDictionary internally implements similar indirection)
// Update the contents of the AccountCache item, requiring either a copy to be returned or the lock to wrap the caller's use of it.
private static readonly ConcurrentDictionary<int, AccountCacheLock> dictionary = new ConcurrentDictionary<int, AccountCacheLock>();
public static AccountCache Get(int accountId, SiteEntities refreshSource) {
AccountCacheLock accountCacheLock = dictionary.GetOrAdd(accountId, k => new AccountCacheLock());
AccountCache accountCache;
lock (accountCacheLock) {
accountCache = accountCacheLock.AccountCache;
}
if (accountCache == null || accountCache.ExpiresOn < DateTime.UtcNow) {
accountCache = new AccountCache(refreshSource.Accounts.Single(a => a.Id == accountId));
lock (accountCacheLock) {
accountCacheLock.AccountCache = accountCache;
}
}
return accountCache;
}
public static void Invalidate(int accountId) {
// TODO
}
private AccountCache(Account account) {
ExpiresOn = DateTime.UtcNow.AddHours(1);
Status = account.Status;
CommunityRole = account.CommunityRole;
Email = account.Email;
}
public readonly DateTime ExpiresOn;
public readonly AccountStates Status;
public readonly CommunityRoles CommunityRole;
public readonly string Email;
private class AccountCacheLock {
public AccountCache AccountCache;
}
}
Side question: is there something in the ASP.NET framework that already does this?
You don't need to be doing any locks. The ConcurrentDictionary should handle that pretty well.
Side question: is there something in the ASP.NET framework that already does this?
Of course. It's not specifically related to ASP.NET but you may take a look at the System.Runtime.Caching namespace and more specifically the MemoryCache class. It adds things like expiration and callbacks on the top of a thread safe hashtable.
I don't quite understand the purpose of the AccountCache you have shown in your updated answer. It's exactly what a simple caching layer gives you for free.
Obviously if you intend to be running your ASP.NET application in a web farm you should consider some distributed caching such as memcached for example. There are .NET implementations of the ObjectCache class on top of the memcached protocol.
I also wanted to note that I took a cursory peek inside ConcurrentDictionary, and it looks like item replacements are locked on neither the individual item nor the entire dictionary, but rather the hash of the item (i.e. a lock object associated with a dictionary "bucket"). It seems to be designed so that an initial introduction of a key also does not lock the entire dictionary, provided the dictionary need not be resized. I believe this also means that two updates can occur simultaneously provided they don't produce matching hashes.

Caching Objects with Expensive Build & Allowing Updates

I am working on a caching manager for a MVC web application. For this app, I have some very large objects that are costly to build. During the application lifetime, I may need to create several of these objects, based upon user requests. When built, the user will be working with the data in the objects, resulting in many read actions. On occasion, I will need to update some minor data points in the cached object (create & replace would take too much time).
Below is a cache manager class that I have created to help me in this. Beyond basic thread safety, my goals were to:
Allow multiple reads against a object, but lock all reads to that object upon an
update request
Ensure that the object is only ever created 1 time if
it does not already exist (keep in mind that its a long build
action).
Allow the cache to store many objects, and maintain a lock
per object (rather than one lock for all objects).
public class CacheManager
{
private static readonly ObjectCache Cache = MemoryCache.Default;
private static readonly ConcurrentDictionary<string, ReaderWriterLockSlim>
Locks = new ConcurrentDictionary<string, ReaderWriterLockSlim>();
private const int CacheLengthInHours = 1;
public object AddOrGetExisting(string key, Func<object> factoryMethod)
{
Locks.GetOrAdd(key, new ReaderWriterLockSlim());
var policy = new CacheItemPolicy
{
AbsoluteExpiration = DateTimeOffset.Now.AddHours(CacheLengthInHours)
};
return Cache.AddOrGetExisting
(key, new Lazy<object>(factoryMethod), policy);
}
public object Get(string key)
{
var targetLock = AcquireLockObject(key);
if (targetLock != null)
{
targetLock.EnterReadLock();
try
{
var cacheItem = Cache.GetCacheItem(key);
if(cacheItem!= null)
return cacheItem.Value;
}
finally
{
targetLock.ExitReadLock();
}
}
return null;
}
public void Update<T>(string key, Func<T, object> updateMethod)
{
var targetLock = AcquireLockObject(key);
var targetItem = (Lazy<object>) Get(key);
if (targetLock == null || key == null) return;
targetLock.EnterWriteLock();
try
{
updateMethod((T)targetItem.Value);
}
finally
{
targetLock.ExitWriteLock();
}
}
private ReaderWriterLockSlim AcquireLockObject(string key)
{
return Locks.ContainsKey(key) ? Locks[key] : null;
}
}
Am I accomplishing my goals while remaining thread safe? Do you all see a better way to achieve my goals?
Thanks!
UPDATE: So the bottom line here was that I was really trying to do too much in 1 area. For some reason, I was convinced that managing the Get / Update operations in the same class that managed the cache was a good idea. After looking at Groo's solution & rethinking the issue, I was able to do a good amount of refactoring which removed this issue I was facing.
Well, I don't think this class does what you need.
Allow multiple reads against the object, but lock all reads upon an update request
You may lock all reads to the cache manager, but you are not locking reads (nor updates) to the actual cached instance.
Ensure that the object is only ever created 1 time if it does not already exist (keep in mind that its a long build action).
I don't think you ensured that. You are not locking anything while adding the object to the dictionary (and, furthermore, you are adding a lazy constructor, so you don't even know when the object is going to be instantiated).
Edit: This part holds, the only thing I would change is to make Get return a Lazy<object>. While writing my program, I forgot to cast it and calling ToString on the return value returned `"Value not created".
Allow the cache to store many objects, and maintain a lock per object (rather than one lock for all objects).
That's the same as point 1: you are locking the dictionary, not the access to the object. And your update delegate has a strange signature (it accepts a typed generic parameter, and returns an object which is never used). This means you are really modifying the object's properties, and these changes are immediately visible to any part of your program holding a reference to that object.
How to resolve this
If your object is mutable (and I presume it is), there is no way to ensure transactional consistency unless each of your properties also acquires a lock on each read access. A way to simplify this is to make it immutable (that why these are so popular for multithreading).
Alternatively, you may consider breaking this large object into smaller pieces and caching each piece separately, making them immutable if needed.
[Edit] Added a race condition example:
class Program
{
static void Main(string[] args)
{
CacheManager cache = new CacheManager();
cache.AddOrGetExisting("item", () => new Test());
// let one thread modify the item
ThreadPool.QueueUserWorkItem(s =>
{
Thread.Sleep(250);
cache.Update<Test>("item", i =>
{
i.First = "CHANGED";
Thread.Sleep(500);
i.Second = "CHANGED";
return i;
});
});
// let one thread just read the item and print it
ThreadPool.QueueUserWorkItem(s =>
{
var item = ((Lazy<object>)cache.Get("item")).Value;
Log(item.ToString());
Thread.Sleep(500);
Log(item.ToString());
});
Console.Read();
}
class Test
{
private string _first = "Initial value";
public string First
{
get { return _first; }
set { _first = value; Log("First", value); }
}
private string _second = "Initial value";
public string Second
{
get { return _second; }
set { _second = value; Log("Second", value); }
}
public override string ToString()
{
return string.Format("--> PRINTING: First: [{0}], Second: [{1}]", First, Second);
}
}
private static void Log(string message)
{
Console.WriteLine("Thread {0}: {1}", Thread.CurrentThread.ManagedThreadId, message);
}
private static void Log(string property, string value)
{
Console.WriteLine("Thread {0}: {1} property was changed to [{2}]", Thread.CurrentThread.ManagedThreadId, property, value);
}
}
Something like this should happen:
t = 0ms : thread A gets the item and prints the initial value
t = 250ms: thread B modifies the first property
t = 500ms: thread A prints the INCONSISTENT value (only the first prop. changed)
t = 750ms: thread B modifies the second property

Global Variable between two WCF Methods

I have two Methods in a WCF Service say
Method1()
{
_currentValue = 10;
}
Method2()
{
return _currentValue;
}
I have a situation in which, i need to set a value in Method1() and read it in Method2().
I tried using static variable like public static int _currentValue, i could able to read the value set in Method1() in Method2().
But the issue is, i want this variable to react like separate instance variable for each request made. i.e., right now below is the problem
Browser 1 :
- Method1() is called
=> sets _currentValue = 10;
- Method2() is called
=> returns _currentValue = 10;
Browser 2:
- Method2() is called
=> returns _currentValue = 10;
Actually the value set is Browser 1 is static, so in Browser 2
the same value is retrieved.
What i am trying to implement is the variable should act like a new instance for each request made (when calling from each browser). What should i use in this case? a session?
You're going to need some mechanism for correlation because you have two completely different sessions calling into different methods. So I would recommend using a private key that both callers know.
It is a bit impossible for me to know what that key can be because I can't really gather anything from your question, so only you know that, but the simple fact is you're going to need correlation. Now, once you determine what they can use you can do something like this.
public class SessionState
{
private Dictionary<string, int> Cache { get; set; }
public SessionState()
{
this.Cache = new Dictionary<string, int>();
}
public void SetCachedValue(string key, int val)
{
if (!this.Cache.ContainsKey(key))
{
this.Cache.Add(key, val);
}
else
{
this.Cache[key] = val;
}
}
public int GetCachedValue(string key)
{
if (!this.Cache.ContainsKey(key))
{
return -1;
}
return this.Cache[key];
}
}
public class Service1
{
private static sessionState = new SessionState();
public void Method1(string privateKey)
{
sessionState.SetCachedValue(privateKey, {some integer value});
}
public int Method2(string privateKey)
{
return sessionState.GetCachedValue(privateKey);
}
}
It sounds like you may need to use the per session instance context mode for the WCF service. This will allow you to maintain state on a per session basis, so member variables in the service instance will persist between method calls from the same proxy instance. Because each user has their own session, the state of the service instance will vary by user.
Check out this article for more information: http://msdn.microsoft.com/en-us/magazine/cc163590.aspx#S2
You have made your variable static, and this is what's causing the problem. static means that every instance of your class shares the variable, but all you really need is a variable declared outside of your methods, like this:
private int _currentValue;
Method1()
{
_currentValue = 10;
}
Method2()
{
return _currentValue;
}
This variable will be reated separately for each instance of your class - preserving this value between requests for a given user is a separate problem. (A session is one possible solution.)
WCF has provided three ways by which you can control WCF service instances:
Per call
Persession
Single instance
You will find the best solution by reading this
Three ways to do WCF instance management
Seems like an old thread but in case somebody is still interested, this can be achieved by just asking WCF to run a single instance of your service. Add the following line (decorator) to the definition of your class
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
If you want the behavior only for the same session but not across clients then you can mark it as per session by the following service behavior
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
The other option is per call which is the default option.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]

How to pass method as a parameter for another method

I need to examine in "parent" object is there an acceptable at a definite moment to call some method in the "child". For example, parent object (component) includes child objects (or component parts in other words) and parent is disposing now, so all (or particlar) child activities must be prohibited (i.e. starting new service threads, enqueueing new client requests, ...).
public class Parent
{
public bool IsMethodCallAcceptable(reference_to_method) {...}
}
public class Child
{
public int SomeMethod(int intArg, string stringArg)
{
if(!_parent.IsMethodCallAcceptable(reference_to_SomeMethod_with_actual_args))
throw new ...
...
}
private void AnotherMethod(string param = null) {...}
{
if(!_parent.IsMethodCallAcceptable(reference_to_AnotherMethod_with_actual_args))
throw new ...
...
}
private Guid ThirdMethod()
{
if(!_parent.IsMethodCallAcceptable(reference_to_ThirdMethod))
throw new ...
...
}
}
Is there any way to do it?
Note: I am answering your question, not your title. Others have answered the title.
Some objects have an isDisposed property, if your parent implements that and that is the only time you don't want to call methods, then yes. Otherwise no. If you control the source for the parent, you could add a property that does what you want.
If you don't control the source and you want to check more than isDisposed or the parent doesn't implement isDisposed, you might be able to check publicly exposed properties, but generally you should assume that if a method is exposed to the public, that it is acceptable to call it at any time. If you're calling private methods via reflection, then you're taking chances.
Edit in response to comment:
Given your description, delegates won't give you any additional capability that you can't do easier by adding properties and methods to the parent (if you don't control the source, they won't help at all). The best method for dealing with your described scenario (CAR.ENGINE.START when out of gas, is for the Start method to either throw an exception or return a value indicationg the result of the attempt to start the engine).
Use delegates?
http://msdn.microsoft.com/en-us/library/ms173171%28v=vs.80%29.aspx
The easiest way is to pass an URI instead of a reference:
"NS.Child.ThirdMethod" for example.
Otherwise, a delegate is what is the closest to a function reference. You can pass that if you want.
However, this method is not compliant with OOP conception rules: Base class should know nothing about its children classes.
It's better to use some kind of locking mechanism to tell the children that they can't have access to the resources.
use func Func<T, TResult>
link
If these methods are native to the child class, the parent can't know anything about them for sure. Rice's Theorem will cause you all kinds of problems, if you could even see the code. Same problem (but to a lesser degree) if they're native to the parent class and are being overridden in the child, since you can't really guarantee that the child class will be doing everything (and only those things) that the parent class does; in fact, you can all but guarantee it will do something different. (If it didn't, why override?)
If they're native to the parent class and not overridable in the child, then just check whether the object is in a valid state for doing such a thing and throw an exception if it isn't.
As far as the actual validity check, for your example you can have a method like bool IsDisposing(); for other cases, you might keep track of the state in some other way. A private method like CanDoThisThing() might help, for example. Having a method that takes a generic operation name (not an operation; we already established the infeasibility of that) seems kinda broken to me.
Thank you all again, the result in the first approach is listed below
public class Component
{
public ComponentPart SomeComponentPart1 { get; private set; }
public ComponentPart SomeComponentPart2 { get; private set; }
public Component()
{
SomeComponentPart1 = new ComponentPart(this);
SomeComponentPart2 = new ComponentPart(this);
}
public bool IsMethodCallAcceptable(MethodCallExpression method, object[] parameters)
{
// collect needed information about caller
var caller = (method.Object as ConstantExpression).Value;
var methodName = method.Method.Name;
var paramsArray = new Dictionary<string, object>();
for (int i = 0; i < method.Arguments.Count; i++)
paramsArray.Add((method.Arguments[i] as MemberExpression).Member.Name, parameters[i]);
// make corresponding decisions
if (caller == SomeComponentPart2)
if (methodName == "SomeMethod")
if ((int) paramsArray["intArg"] == 0 || (string) paramsArray["stringArg"] == "")
return false;
return true;
}
}
public class ComponentPart
{
private Component Owner { get; set; }
public ComponentPart(Component owner)
{
Owner = owner;
}
public int SomeMethod(int intArg, string stringArg)
{
// check if the method call with provided parameters is acceptable
Expression<Func<int, string, int>> expr = (i, s) => SomeMethod(intArg, stringArg);
if (!Owner.IsMethodCallAcceptable(expr.Body as MethodCallExpression, new object[] { intArg, stringArg }))
throw new Exception();
// do some work
return stringArg.Length + intArg;
}
public void AnotherMethod(bool boolArg, Dictionary<Guid, DateTime> crazyArg, string stringArg, object objectArg)
{
// check if the method call with provided parameters is acceptable
Expression<Action<bool, Dictionary<Guid, DateTime>, string, object>> expr =
(b, times, arg3, arg4) => AnotherMethod(boolArg, crazyArg, stringArg, objectArg);
if (!Owner.IsMethodCallAcceptable(expr.Body as MethodCallExpression, new [] { boolArg, crazyArg, stringArg, objectArg }))
throw new Exception();
// do some work
var g = new Guid();
var d = DateTime.UtcNow;
}
}
This is variant how to check method calls, the same approach can be used in order to check properties values changes, while some ComponentPart' methods and properties can check some public Component.State property (via ComponentPart.Owner) instead of calling Component.IsMethodCallAcceptable or Component.IsPropertyChangeAcceptable.

Categories

Resources