Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET MVC 5异步上下文管理_C#_Asp.net Mvc_Asp.net Mvc 5_Async Await_C# 5.0 - Fatal编程技术网

C# ASP.NET MVC 5异步上下文管理

C# ASP.NET MVC 5异步上下文管理,c#,asp.net-mvc,asp.net-mvc-5,async-await,c#-5.0,C#,Asp.net Mvc,Asp.net Mvc 5,Async Await,C# 5.0,我有一个相当标准的MVC5应用程序,由存储库层、服务层和控制器层组成。为了保持每一层的解耦性和可测试性,我使用Ninject进行依赖注入 为了复习新技能,我决定使用新的任务控制器操作,对服务和控制器方法使用异步/await-on-IO绑定操作 通常我只是像这样使用InRequestScope绑定 kernel.Bind<IDbContext>().To<BlogContext>().InRequestScope(); kernel.Bind().To().InReque

我有一个相当标准的MVC5应用程序,由存储库层、服务层和控制器层组成。为了保持每一层的解耦性和可测试性,我使用Ninject进行依赖注入

为了复习新技能,我决定使用新的任务控制器操作,对服务和控制器方法使用异步/await-on-IO绑定操作

通常我只是像这样使用InRequestScope绑定

kernel.Bind<IDbContext>().To<BlogContext>().InRequestScope();
kernel.Bind().To().InRequestScope();
一般来说,这现在可以正常工作了,但是如果我选择调试我的应用程序,或者将多个被跟踪的实体框架对象连接在一起并保存,我会发现上下文已经被处理,或者我会遇到跟踪问题。我明白为什么会发生这种情况,这是完全合乎逻辑的,因为操作不再在IIS线程上进行,所以Ninject如何知道它应该使用相同的上下文

为了解决这个问题,我可以将我的上下文从我的服务层传递到每个存储库调用中,如果需要,甚至可以从控制器层传递到存储库调用中。但是我觉得这看起来很混乱,如果可能的话,我宁愿直接管理这个对象的上下文

以优雅/简约的方式处理此问题的最佳策略是什么,同时使我的代码与下面给出的示例类似

下面是我的一个控制器方法的示例

    public virtual async Task<ActionResult> Edit(int id)
    {
        var editViewModel = await BuildDefaultCreateEditViewModel();

        var post = await postService.GetNonDeletedPost(id);
        ...
        ...
        return View(MVC.Admin.Post.Views.CreateEdit, editViewModel);
    }
公共虚拟异步任务编辑(int-id)
{
var editViewModel=等待BuildDefaultCreateEditViewModel();
var post=等待postService.getnondeletepost(id);
...
...
返回视图(MVC.Admin.Post.Views.CreateEdit、editViewModel);
}
服务方式

    public async Task<PostDTO> GetNonDeletedPost(int postId)
    {
        return (await PostRepostiory.GetPost(postId)).ConvertToDTO();
    }
public异步任务getnondeletepost(int postId)
{
return(wait postrepostory.GetPost(postId)).convertto();
}
存储库方法

    public Task<Post> GetPost(int postId)
    {
        return QueryableExtensions.SingleOrDefaultAsync(
                DbSet.Where(post => post.PostId == postId)
                .Include(post => post.PostVersions)
                .Include(post => post.Categories)
                .Include(post => post.Files));
    }
public任务GetPost(int postId)
{
返回QueryableExtensions.SingleOrDefaultAsync(
DbSet.Where(post=>post.PostId==PostId)
.Include(post=>post.PostVersions)
.Include(post=>post.Categories)
.Include(post=>post.Files));
}

在您的帖子和相关评论中,有一些很好的例子说明了如何做到这一点

然而,对于其他一些可能在这里结巴的读者,我想提出一个诚实的问题:你真的需要异步控制器吗?

异步控制器动作释放了处理请求所需的线程数量;然而,如果你没有用完线程,也不太可能用完,那么你在试图解决一个你既没有也不希望遇到的问题的同时,也在制造复杂性。或者:“异步真的是免费的并且总是更好吗?”

实际上,我试图展示一个非常可行的解决方案(可能不是您正在寻找的解决方案),就是不使用异步控制器——如果确实不需要的话(这取决于您的具体情况)

通过解决问题来解决问题的好办法。特别是,我之所以提出这个建议,是因为消除复杂性似乎是目标之一

如何选择使用哪个?列表较长,但最好的两个问题是:

  • 您的物品是否短缺?
  • 如果没有,您的项目是否受CPU限制?


从上面的链接“在CPU绑定的操作上使用异步操作方法不会带来任何好处,也不会导致更多的开销。”

是否使用DbContextFactory?我倾向于使用
TransientScope
而不是Request,而且我从来没有遇到过任何问题。我实际上希望我可以以类似于使用InRequestScope的DbContextFactory的方式使用Ninject。如果我继续使用DBContextFacotry,那么我如何知道异步线程属于哪个请求的问题仍然很明显,我如何否定这个问题?至于使用临时作用域,它将为每个存储库创建一个新的上下文,这对于使用一个存储库的服务很好,但当我使用多个(门面模式)将对象缝合在一起并保存时将不起作用,因为来自不同存储库的对象将处于不同的跟踪上下文中。这就是我如何使用ninject,以及DbContextFactory,它允许我将上下文注入到存储库中(全部在TransientScope中)对不起,您的“postService”字段每个请求都依赖于默认MVC使用Niject或STATITY?如果您没有密集编译到IOC,请尝试使用非常简单的构建上下文,并使用此