我正在尝试通过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);
}
}
我尝试/摆弄的东西:
所以我猜我偶然发现了一个“修复”,但有人可以解释为什么其中一个会以如此奇怪的方式失败,而另一个会完全正常工作?
在实际应用程序中,API调用没有async / await对,但是 的代码使得调用实际上是使用async / await。
这是失败的存储库类,导致我调查此问题:
public async Task<MyObject> Load(string id)
{
return await _session.LoadAsync<MyObject>(id);
}
答案 0 :(得分:4)
失败的第一部分是按照设计,对于ASP.Net异步调用,当您调用返回的任务上的Result并且调用返回数据时需要相同的同步上下文时,您阻止同步上下文。请通过 Stephen Cleary 查看以下link,其中详细说明了相同的机制。
第二部分有效,因为这是使用它的正确方法,它不再陷入死锁。第一部分只能在你使用Console应用程序时才能工作,该应用程序没有同步上下文来阻止,甚至其他类似UI的UI也会有类似的问题,需要使用代码的第二部分