2016-06-20 2 views
1

Я не получаю ответ от метода async DocumentDB ReplaceDocument при работе в веб-контексте (IIS). При работе на локальном компьютере он работает нормально. Из моих исследований это похоже на конфликтный тупик с потоком пользовательского интерфейса?Call to ReplaceDocumentAsync метод не возвращается

Я получаю хорошие отзывы от других асинхронных вызовов примерно так:

this.Client.ReadDatabaseAsync(UriFactory.CreateDatabaseUri(this.DatabaseName)).Result; 
// and 
this.Client.CreateDatabaseAsync(new Database { Id = this.DatabaseName }).Result; 
// etc 

Я не использую Await как в контексте IIS является, кажется, никогда не отвечают. Я не уверен, почему, поэтому я удалил все асинхронные ожидания и начал использовать .Result, и теперь все работает, кроме метода ниже.

В соответствии с этим вопросом Call to await GetFileAsync() never returns and app hangs in WinRT app. Я установил ConfigureAwait(false) и позвонил GetResult(). Но метод не возвращается, и поток в конце концов закрывается без возврата.

var task = this.Client.ReplaceDocumentAsync(this.GetDocumentLink(d.id), d, options); 
var configuredTask = task.ConfigureAwait(false); 
var awaiter = configuredTask.GetAwaiter(); 
var result = awaiter.GetResult(); 

Я также попытался следующие перестановки:

// in a spereate async method 
await this.Client.ReplaceDocumentAsync(this.GetDocumentLink(d.id), d, options); 
await this.Client.ReplaceDocumentAsync(this.GetDocumentLink(d.id), d, options).ConfigureAwait(false); 

// as well as trying a call back 
.GetAwaiter().OnCompleted(() => /* never gets here either */); 

EDIT

у меня есть это в мой Web.config (через: What's the meaning of "UseTaskFriendlySynchronizationContext"?)

<appSettings> 
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> 
</appSettings> 

and 

<system.web> 
    <compilation debug="true" targetFramework="4.6.1" /> 
    <httpRuntime targetFramework="4.5" /> 
</system.web> 

ответ

4

Я верю тебе 'видя common deadlock issue, который я описываю в своем блоге.

Лучшее решение не, чтобы попытаться избежать его, используя ConfigureAwait(false) везде, потому что он должен быть использован везде. Поэтому, если вы забудете одно место или если есть какой-то библиотечный код, который его не использует (что, к сожалению, является общим), то вы не можете избежать тупика.

Лучшим решением является использование await. Замените каждый вызов Task.Wait(), Task<T>.Result и Task.GetAwaiter().GetResult() с await:

await this.Client.ReadDatabaseAsync(UriFactory.CreateDatabaseUri(this.DatabaseName)); 
await this.Client.CreateDatabaseAsync(new Database { Id = this.DatabaseName }); 

var result = await this.Client.ReplaceDocumentAsync(this.GetDocumentLink(d.id), d, options); 

Я не использую Await как в контексте IIS является, кажется, никогда не отвечает.

Пожалуйста, убедитесь, что вы ориентируетесь .NET 4.5 и установили targetFramework 4,5 в вашем web.config.

+0

Я добавил свой контент в веб-конфигурацию, также, я дам асинхронную версию сверху вниз, я запускаюсь из WebAPI, что бы я ни беспокоился, прежде чем погрузиться в это изменение в 300 строк? – ohmusama

+0

@ohmusama: Если у вас есть синхронные API-интерфейсы, возможно, быстрее перейти на синхронизацию. –

+0

Я думаю, что проблема в 'ReplaceDocumentAsync' в библиотеке documentDb не может использовать ConfigureAwait (false), и поэтому я не могу ждать ее. Наверное, опечатка.Я собираюсь разложить его и проверить. – ohmusama

0

В моем случае были аналогичные задачи cancel/error, внутреннее исключение показано как «DictionaryError» или «Исключение агрегации». По крайней мере, я выясняю, что основной причиной, вызванной проблемой, было просто использовать endpoint для эмулятора CosmosDb с помощью http: //. После смены https://localhost:8081 - все началось.

Смежные вопросы