Search code examples
c#wcf-data-servicesthreadstaticcallcontext

CallContext is carrying foreward the previous data which was set


I have this condition where I see that the thread's CallContext is carrying foreward the data in consequent calls.

Consider I have a simple API which when queired, will set one data entry into CallContext using :

// entry to the API execution within OnStartProcessingRequest method of DataService
if(CallContext.LogicalGetData("data") != null)
    CallContext.LogicalSetData("data", someValue)
print("data " + CallContext.LogicalGetData("data"))

When I see the logs after some API queries, I see similar logs.

| thread | log |
| 237 | data 23 |
| 145 | data 19 |
| 872 | data 78 |
| 237 | data 23 |

My concern is why did thread with ID 237 pick up old data? i.e. 23
I'm sure the control didn't go inside the LogicalSetData block of code as it already had data.

I'm not sure why this is happening? Can anyone help me with this?

The service is a WCF dataservice. Call is being made from postman REST client.


Solution

  • Consider switching to OperationContext as it is built-in and natural context for storing data for a specific request.
    CallContext.GetData will get the data that was set via SetData from the same thread. Data stored via CallContext.LogicalSetData is considered to be "logical thread" local. That is, any data that is stored via CallContext.LogicalSetData will be "flowed" to any child threads. If you call CallContext.LogicalGetData in the same thread or any child threads, you will get the data that was stored by that thread's (or the parent thread's) call to CallContext.LogicalSetData. Better description in this great article.
    I was unable to find any information that CallContext must be clean on each request start, however I found this old article, describing custom ICallContextInitializer implementation. It says:

    WCF by default is more frugal than other stacks, such as ASP.NET, when it comes to protecting state. Saving and restoring lots of thread-local settings takes time regardless of whether you actually did something with those settings or not. WCF tries not to do as much on your behalf so that you don't have to pay for cleanup unless you're using those features. It does however give you the hooks necessary to arrange for this cleanup to take place at the appropriate time.