Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

async WCF method WebOperationContext is null after await

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?

like image 672
Justin Harvey Avatar asked Nov 08 '12 13:11

Justin Harvey


1 Answers

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).

like image 131
Stephen Cleary Avatar answered Nov 08 '22 22:11

Stephen Cleary