다음을 통해 공유


Fix for Exception Reading Typed Headers

This week I'll be running a series covering fixes for WCF that may be hard to find and explaining the details behind each problem.

The dispatch operation formatter is the component that deserializes a message into objects. When building the objects out of the message headers in the message, the implementation of the operation formatters for XmlSerializer and DataContractSerializer uses an internal class called TypedHeaderManager. A TypedHeaderManager is created for each seen content type and then cached to make the object creation process faster in the future.

The cache for TypedHeaderManager objects uses a reader-writer lock to improve concurrency. After the first few messages it should be increasingly rare to need to add items to the cache, making most accesses be reads rather than writes. The cache is first tested under the reader lock for an instance of TypedHeaderManager. The writer lock is acquired if an instance didn't exist for the seen content type to add the entry.

The original code didn't check whether some other thread created a TypedHeaderManager instance for the same type while the writer lock was being acquired. This can happen if multiple messages using a particular header type for the first time arrive at nearly the same time. You're encountering this problem if you see the following exception.

 System.ArgumentException: An item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at System.ServiceModel.TypedHeaderManager.GetTypedHeaderManager(Type t)

This is an example where double-checked locking was intended but implemented incorrectly.

A fix for this problem was in the Application Compatibility Update for .Net 3.5 Service Pack 1.

Comments

  • Anonymous
    February 01, 2010
    I have had this exception with .net 4.0. We are developing our project with vs2010

  • Anonymous
    February 01, 2010
    Hi Pablo, What version of .Net 4 did you try?  It looks to be fixed in .Net 4 Beta 2.

  • Anonymous
    February 01, 2010
    I think it could be with SL 4.0. I do not remember exactly the technology because I am in 3 projects concurrently at this time, but It must be or in SL 4.0 or in .NET 4.0. Check if you like, if it is solved in both I beg your pardon.

  • Anonymous
    February 02, 2010
    Thanks Pablo.  I'll see if there are differences there between .Net 4 and Silverlight.