代码之家  ›  专栏  ›  技术社区  ›  LP13

viewcomponent invokeasync方法和非异步操作

  •  0
  • LP13  · 技术社区  · 8 年前

    ASP.NET核心 ViewComponent 我们必须在 InvokeAsync 返回 IViewComponentResult . 但是我没有 async 在调用方法内部执行的逻辑。所以基于 SO post here 我已经移除了 异步 限定符并返回 Task.FromResult

    public Task<IViewComponentResult> InvokeAsync(MyBaseModel model)
    {        
        var name = MyFactory.GetViewComponent(model.DocumentTypeID);        
        return Task.FromResult<IViewComponentResult>(View(name, model));
    }
    

    然后在视野中(因为我没有 异步的 我不使用 await 这里)

    @Component.InvokeAsync("MyViewComponent", new { model = Model })
    

    然而,视图显示:

    System.Threading.Tasks.Task 1[microsoft.aspnetcore.html.ihtmlcontent]`

    2 回复  |  直到 8 年前
        1
  •  2
  •   Chris Pratt    8 年前

    你必须 await 这个 Component.InvokeAsync . 您的方法不做任何异步操作这一事实无关紧要。方法本身是异步的。

    不过,这有点过于简单化了。坦白地说 async / 等待 关键词掩盖了这一切的复杂性。准确地说,与其将这些类型的方法称为“异步”,不如将它们讨论为“任务返回”。任务本质上是一些操作的句柄。该操作可能是异步的 同步。它与AsiNC最密切相关,因为在大多数情况下,打包任务中的同步操作将是毫无意义的。然而,问题是,仅仅因为某个东西必须返回一个任务并不意味着它 必须 是异步的。

    Async只允许 可能性 一个线程开关。在有一些操作(通常涉及I/O)的情况下,这会导致工作线程在一段时间内空闲,线程可用于其他工作和原始工作。 可以 在不同的线程上完成。注意这里被动语态的用法。异步操作不涉及线程切换;任务可以在同一线程上完成,就好像它是同步一样。如果底层操作已经完成,任务甚至可以立即完成。

    在您的场景中,您没有做任何异步工作,这很好。但是,方法定义要求 Task<T> 作为回报,所以你必须使用 Task.FromResult 以返回实际结果。这些都是很标准的东西,似乎已经被你理解了。我想,你错过的是,你在想,既然你不是在做任何非同步的工作,那就错了。 等待 . 没有什么神奇的 等待 关键字;它基本上只是意味着在任务完成之前保持在这里。如果没有异步工作要做,就像这里的情况一样,同步代码将正常运行,并且在完成后返回调用代码,不过,为了方便起见, 等待 还执行另一个重要功能:它展开任务。

    这就是你的问题所在。由于您没有等待,任务本身被返回到Raxor视图处理流水线中。它不知道该怎么做,所以它默认做什么,只调用 ToString 关于它,因此你得到的文本。打开包装,你就可以 IViewComponentResult Razor 知道该怎么办。

        2
  •  1
  •   David Liang    8 年前

    如果在invoke方法中执行的逻辑是同步的,即没有 await ,您有两个选项:

    1. 您可以在没有 async 关键字,它应该返回 Task.FromResult<T>
    2. 使用 public IViewComponentResult Invoke() 相反。

    我认为 异步 关键字启用 等待 关键字,这是非常重要的。没什么特别的 异步的 关键字。

    在呈现视图的主线程上,因为tag helper方法 调用视图组件 Component.InvokeAsync() 是可以等待的,你需要 等待 关键字启动任务。 等待 检查视图组件呈现是否已完成。如果有,那么主线程就继续运行。否则主线程将告诉viewcomponent运行。

    推荐文章