RavenDb LoadAsync不返回而不是抛出异常

时间:2016-05-15 02:00:32

标签: c# asynchronous async-await task ravendb

我正在尝试通过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); 
    } 

1 个答案:

答案 0 :(得分:4)

失败的第一部分是按照设计,对于ASP.Net异步调用,当您调用返回的任务上的Result并且调用返回数据时需要相同的同步上下文时,您阻止同步上下文。请通过 Stephen Cleary 查看以下link,其中详细说明了相同的机制。

第二部分有效,因为这是使用它的正确方法,它不再陷入死锁。第一部分只能在你使用Console应用程序时才能工作,该应用程序没有同步上下文来阻止,甚至其他类似UI的UI也会有类似的问题,需要使用代码的第二部分