实体框架使用异步控制器处理Webapi/MVCpublicValueController(){_db=newEstateContext();}[HttpPost]publicasyncvoidDoStuff(stringid){varentity=await_db.Estates.FindAsync(id);//现在我们的方法退出并调用Dispose方法//在处理后返回这里_db.SaveChanges();//_db已处理}protectedoverridevoidDispose(booldisposing){base.Dispose(disposing);_db.Dispose();每个ApiController/Controller都实现了IDisposable接口。所以在Dispose方法中我想释放任何资源,如DbContext。但是如果使用async,这个Dispose方法会在await第一次发生时被调用。所以在等待之后我已经处理了DbContext。那么在使用异步时处理EF上下文的最佳方式是什么?原来不能依赖controller中的Dispose方法?但是如果使用async,这个Dispose方法会在await第一次发生时被调用。@Konstantins的回答是正确的,但请允许我详细说明为什么会这样。当您使用asyncvoid方法时,您基本上是在为方法调用创建一个“即发即弃”语义,因为该方法的调用者不能通过await异步等待它,因为它返回void而不是等待的形式(例如任务)。因此,虽然WebAPI确实支持异步方法,但在调用您的操作时,它似乎是一个返回void的同步方法,然后ASP.NET运行时继续处理您的控制器,因为它假定您已完成。当暴露一个Task或Task时,你明确地告诉调用者“听着,这个方法是异步的,最终会返回一个值”。ASP.NET运行时知道您的控制器尚未完成调用其操作,并等待操作实际完成。这就是为什么要这样调用:[HttpPost]publicasyncTaskDoStuffAsync(stringid){varentity=await_db.Estates.FindAsync(id);_db.SaveChanges();}作品。作为旁注-EFDbContext旨在尽快使用和处理。将它们用作多个操作的全局变量是一个坏主意,因为它们也不是线程安全的。我会建议一个不同的模式,其中每个操作初始化和处理DbContext:);db.SaveChanges();正如@Wachburn在评论中指出的那样,这种方法确实不易测试。如果您确保在每个操作完成后处理控制器和操作并且不重复使用上下文,则可以通过DI容器注入DbContext。您需要在异步方法中创建EstateContext的新实例。[HttpPost]publicasyncvoidDoStuff(stringid){EstateContextdb=newEstateContext();varentity=awaitdb.Estates.FindAsync(id);db.SaveChanges();但是,我相信如果您将控制器操作更改为Task的返回类型,那么您应该能够重用作为控制器成员的上下文。以上就是C#学习教程:实体框架使用Webapi/MVC中的异步控制器来处理和分享所有的内容。如果对大家有用,需要了解更多C#学习教程,希望大家多多关注——_db.SaveChanges();}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
