我正在尝试通过 WebAPI 调用从 RavenDb 加载文档。当我打开异步 IDocumentSession 并调用 LoadAsync 时,我没有收到任何异常或结果,并且线程立即退出,没有错误代码。
我能够绕过 API 的所有结构并重现错误。
这是不起作用的代码:
public IHttpActionResult GetMyObject(long id)
{
try
{
var session = RavenDbStoreHolderSingleton.Store.OpenAsyncSession();
var myObject= session.LoadAsync<MyObject>("MyObject/1").Result;
return Ok(myObject);
}
catch (Exception e)
{
return InternalServerError(e);
}
}
我只是将对象的 Id 硬编码为 1 进行测试,但为不存在的对象(例如“MyObject/1”)调用该函数会得到相同的结果。
但是,此代码有效:
public async Task<IHttpActionResult> GetMyObject(long id)
{
try
{
var session = RavenDbStoreHolderSingleton.Store.OpenAsyncSession();
var myObject= await session.LoadAsync<MyObject>("MyObject/1");
return Ok(myObject);
}
catch (Exception e)
{
return InternalServerError(e);
}
}
我尝试/摆弄的事情:
- 更改调试中捕获的异常
- 仔细监控 Raven Studio,看看是否能发现任何问题(我没有发现,但我不确定我是否找对了地方)
- 在不附加调试器的情况下运行 API,以查看是否发生错误或 Raven Studio 中是否显示某些内容(无变化)
所以我想我偶然发现了一个“修复”,但是有人可以解释为什么其中一个会以如此奇怪的方式失败,而另一个却可以完美地工作?
在实际应用程序中,API 调用没有 async/await 对,但是进行调用的代码实际上使用了 async/await。
这是失败的存储库类,这导致我调查这个问题:
public async Task<MyObject> Load(string id)
{
return await _session.LoadAsync<MyObject>(id);
}
最佳答案
失败的第一部分是按照设计,对于 ASP.Net 异步调用,当您在返回的任务上调用结果并且调用需要相同的同步上下文才能返回数据时,您将阻塞同步上下文。查看以下link作者:Stephen Cleary,其中详细解释了相同的机制。
第二部分有效,因为这是使用它的正确方法,并且它不再陷入僵局。第一部分仅在您使用控制台应用程序时才有效,该应用程序没有要阻止的同步上下文,甚至像 winforms 这样的其他 UI 也会有类似的问题,需要使用代码的第二部分
关于c# - RavenDb LoadAsync 不返回也不抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37233772/