调用ReplaceDocumentAsync方法无法返回

时间:2016-06-20 18:44:31

标签: c# asynchronous async-await azure-cosmosdb

在Web上下文(IIS)中运行时,我没有从异步DocumentDB ReplaceDocument方法获得响应。在本地运行时,它工作得很好。根据我的研究,这似乎与UI线程的冲突死锁有关吗?

我从其他异步调用中得到了很好的响应:

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

我没有在IIS上下文中使用await似乎永远不会响应。我不知道为什么,所以我删除了所有的异步等待,并开始使用.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 */);

修改

我在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>

2 个答案:

答案 0 :(得分:4)

我相信你会看到我在博客上描述的common deadlock issue

最好的解决方案试图通过在任何地方使用ConfigureAwait(false)来避免它,因为必须使用无处不在。因此,如果您忘记了一个地方,或者某些库代码没有使用它(这很常见),那么就无法避免死锁。

最好的解决方案是使用await。将Task.Wait()Task<T>.ResultTask.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中将web.config设置为4.5。

答案 1 :(得分:0)

在我的情况下,有类似的任务取消/错误,显示内部异常&#34; DictionaryError&#34;或聚合异常。至少我发现造成问题的主要原因只是使用端点到cosmosDb模拟器和http://。更改后https://localhost:8081 - 一切都开始工作了。