Keep OperationContext in task parallel library
-
21-06-2021 - |
سؤال
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?
المحلول 3
Seems the only way is to add something to the CallContext, just like the current Principal is stored...
نصائح أخرى
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);
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.