Асинхронные вызовы клиента 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 :
Не используйте асинхронный шаблон "ожидания" в блоке 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(); } }