Async 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);
}
}
Я нашел следующий комментарий из документов:
Не используйте асинхронный шаблон "ожидание" в блоке OperationContextScope. Когда это происходит, он может работать в другом потоке, а OperationContextScope - конкретный поток. Если вам нужно вызвать "ожидание" для асинхронного вызова, используйте его вне блока OperationContextScope.
Так что, похоже, я неправильно звоню в службу. Но каков правильный путь?
Ответы
Ответ 1
Все, кажется, хорошо работает со следующим кодом:
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);
}
}
Ответ 2
Это известная проблема, и для тех, кто застрял в этом, вы можете просто запустить ваш вызов синхронно. Используйте 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();
}
}