Асинхронные вызовы клиента WCF с пользовательскими заголовками: этот OperationContextScope удаляется из строя
Я вызываю службу WCF из приложения WinRT. Служба требует, чтобы для проверки подлинности были установлены некоторые заголовки. Проблема в том, что если я это сделаю несколько вызовов к сервису одновременно, Я получаю следующее исключение:
этот OperationContextScope удаляется из строя.
текущий код выглядит следующим образом:
public async 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,
};
var result = await client.GetDataFromServerAsync(request);
}
}
Я нашел следующий комментарий от docs:
Не используйте асинхронный шаблон "await" в блоке OperationContextScope. Когда происходит продолжение, оно может выполняться в другом потоке, а OperationContextScope зависит от потока. Если вам нужно вызвать "await" для асинхронного вызова, используйте его вне блока OperationContextScope.
таким образом, кажется, я явно вызываю службу неправильно. Но каков правильный путь?
2 ответов
все, кажется, работает довольно хорошо со следующим кодом:
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);
}
}
Это известная "проблема" и для тех, кто застрял с этим, вы можете просто запустить ваш звонок синхронно. Используйте GetAwaiter ().GetResult (); вместо этого, поскольку он вообще не планирует задачу, он просто блокирует вызывающий поток до завершения задачи.
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();
}
}