Async WCF client calls with custom headers: This OperationContextScope is being disposed out of order
According to Microsoft documentation:
Do not use the asynchronous "await" pattern within a OperationContextScope block. When the continuation occurs, it may run on a different thread and OperationContextScope is thread specific. If you need to call "await" for an async call, use it outside of the OperationContextScope block.
So the simplest proper solution is:
Task<ResponseType> task;
using (new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = GetHeader();
var request = new MyRequest(...);
{
context = context,
};
task = client.GetDataFromServerAsync(request);
}
var result = await task;
This is a known "issue" and for anyone stuck with this, you can simply run your call synchronously. Use GetAwaiter().GetResult(); instead since it doesn't schedule a Task at all, it simply blocks the calling thread until the task is completed.
public Result CallServer()
{
var address = new EndpointAddress(url);
var client = new AdminServiceClient(endpointConfig, address);
using (new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = GetHeader();
var request = new MyRequest(...);
{
context = context,
};
return client.GetDataFromServerAsync(request).GetAwaiter().GetResult();
}
}
Everything seems to work quite well with the following code:
public async void TestMethod()
{
var result = await CallServerAsync();
}
public Task<Result> CallServerAsync()
{
var address = new EndpointAddress(url);
var client = new AdminServiceClient(endpointConfig, address);
using (new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = GetHeader();
var request = new MyRequest(...);
{
context = context,
};
return client.GetDataFromServerAsync(request);
}
}