we have somewhere in a deep abstraction assembly a WCF behavior that reads data from the OperationContext.Current, when this code is executed from within a Task, the OperationContext.Current is empty, is it possible to solve this inside the abstraction assembly or will we need to add some code to all consumers of this assembly?
-
Who starts the `Task`? The consumer? Is any code from the abstraction assembly executed before starting the `Task`? – svick Jul 16 '12 at 08:46
-
no, that is the problem, the consumer starts the tasks :( – Tim Mahy Jul 16 '12 at 09:07
3 Answers
Was facing a similar issue. Was calling a service through Task.
The following code snippet worked out. The OperationContext.Current
was explicitly set by casting the state
variable being provided by Task
before the call to service is done.
Task<int> taskContactsCount = Task.Factory.StartNew<int>((state) =>
{
int count = 0;
try
{
OperationContext.Current = (OperationContext)state;
TestServiceClient testServiceProxy = new TestServiceClient();
var count = testServiceProxy.GetCount();
}
catch (Exception ex)
{
}
return contactsCount;
}, OperationContext.Current);

- 1,050
- 11
- 26
At the point where you create your Task
instance, you should use a closure, like so:
// The operation context.
OperationContext oc = OperationContext.Current;
Task t = Task.Factory.StartNew(() => {
// Do something with context here, it will be valid for
// the life of the operation.
};
You can also call the overload of StartNew
which takes a state
parameter and pass the OperationContext
instance in, casting and using it when needed in the Task
, like so:
Task t = Task.Factory.StartNew(s => {
// s is an object, so need to cast here.
var oc = (OperationContext) c;
// Work with the OperationContext.
},
// Note, this is passed to the delegate through the 's' parameter.
OperationContext.Current);
Note that in both cases, the OperationContext
will only be good for the life of the operation. The completion of the operation should be dependent on the completion of the Task
.
If you are launching a Task
that will run after the operation completes, then you should copy the values you need from the OperationContext
into another structure and pass those into your Task
for processing.

- 73,706
- 19
- 184
- 253
-
yes that I know, but the problem is cannot force the consumer code to not just start a Task and do stuff :) – Tim Mahy Jul 17 '12 at 07:14
-
@TimMahy Then it seems you have to build the context into your abstractions, passing it around where you need it. – casperOne Jul 17 '12 at 11:49
Seems the only way is to add something to the CallContext, just like the current Principal is stored...

- 1,319
- 12
- 28