In the following example, the method is exposed as a WCF service operation and the service is hosted in IIS. On entry into the function the WebOperationContext.Current is set as expected. After the await has finished waiting, however, the WebOperationContext.Current is set to null.
public async Task TestAsync()
{
//WebOperationContext.Current is set
Task t = new Task(()=>Thread.Sleep(10000));
t.Start();
await t;
//WebOperationContext.Current is null
}
This would seem to be a shortcoming, so I wondered if anyone was aware of this and if there were any good ways around it. I realise I could cache a reference to the conext in a local variable, but this doesn't seem great.
Update
One approach that works is
public async Task TestAsync()
{
WebOperationContext ctx = WebOperationContext.Current;
Task t = new Task(()=>Thread.Sleep(10000));
t.Start();
await t;
//ctx is set
}
and also, as others have hinted at, I could do this
public async Task TestAsync()
{
CallContext.LogicalSetData("WebOperationContext.Current", WebOperationContext.Current);
Task t = new Task(()=>Thread.Sleep(10000));
t.Start();
await t;
WebOperationContext ctx = (WebOperationContext)CallContext.LogicalGetData("WebOperationContext.Current");
}
What would be the implications in terms of performance and thread safety of each?
I've heard the WCF team is considering solutions for OperationContext.Current
, and I expect they will address WebOperationContext.Current
as well. See this SO post (note that Jon Cole is on the MS WCF team).
In the meantime, you can capture the value in a variable (which improves testability, and is what I recommend), add it to LogicalCallContext
, or install your own SynchronizationContext
(which would be tricky since you're hosted in IIS which uses its own SynchronizationContext
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With