Tom*_*Tom 8 c# asynchronous async-await c#-5.0
以下代码有效
[Route("case-studies/{slug}")]
public async Task<ActionResult> Details(string slug)
{
var item = await Db.Pages.OfType<CaseStudy>()
.WithSlug(slug)
.FirstOrDefaultAsync();
if (item == null)
{
return HttpNotFound();
}
var related = await Db.Pages.OfType<CaseStudy>()
.Where(r => r.Client == item.Client && r.Id != item.Id)
.Where(r => !r.IsArchived)
.Include(r => r.Media)
.Take(3)
.Project()
.To<RelatedPageModel>()
.ToListAsync();
var archived = await Db.Pages.OfType<CaseStudy>()
.Where(r => r.Client == item.Client && r.Id != item.Id)
.Where(r => r.IsArchived)
.Take(3)
.Project()
.To<RelatedPageModel>()
.ToListAsync();
ViewData.Model = new DetailPageModel<CaseStudy>()
{
Item = item,
RelatedItems = related,
ArchivedItems = archived
};
return View();
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试重构async方法调用如下
[Route("case-studies/{slug}")]
public async Task<ActionResult> Details(string slug)
{
var item = await Db.Pages.OfType<CaseStudy>()
.WithSlug(slug)
.FirstOrDefaultAsync();
if (item == null)
{
return HttpNotFound();
}
var related = await GetRelatedCaseStudies(item, false);
var archived = await GetRelatedCaseStudies(item, true);
ViewData.Model = new DetailPageModel<CaseStudy>()
{
Item = item,
RelatedItems = related,
ArchivedItems = archived
};
return View();
}
private Task<List<RelatedPageModel>> GetRelatedCaseStudies(CaseStudy casestudy, bool archived)
{
return Db.Pages.OfType<CaseStudy>()
.Where(r => r.Client == casestudy.Client && r.Id != casestudy.Id)
.Where(x => x.IsArchived == archived)
.Include(r => r.Media)
.Take(3)
.Project().To<RelatedPageModel>()
.ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)
它没有给我以下错误
在先前的异步操作完成之前,在该上下文上开始第二操作.使用'await'确保在此上下文上调用另一个方法之前已完成任何异步操作.任何实例成员都不保证是线程安全的.
为什么是这样?我怎样才能做到这一点?
更新:
Db在基本控制器中声明如下
private WebSiteDb db;
protected WebSiteDb Db
{
get
{
LazyInitializer.EnsureInitialized(ref db, () => new WebSiteDb());
return db;
}
}
Run Code Online (Sandbox Code Playgroud)
WebSiteDb扩展DbContext,如下所示
[DbConfigurationType(typeof(DbConfig))]
public class WebSiteDb : DbContext
{
static WebSiteDb() {
Database.SetInitializer<WebSiteDb>(new WebSiteDbInitializer());
}
public IDbSet<Page> Pages { get; set; }
public IDbSet<Media> Media { get; set; }
...some missing sets
public WebSiteDb() : base("MyDatabaseName") { }
}
Run Code Online (Sandbox Code Playgroud)
如果我在方法内部等待,则会从方法内部抛出错误
WithSlug()如下
public static IQueryable<T> WithSlug<T>(this IQueryable<T> pages, string slug) where T : Page
{
return pages.Where(p => p.Slug == slug);
}
Run Code Online (Sandbox Code Playgroud)
下面的测试代码工作得很好。显示实施情况.WithSlug( slug )
class Program
{
static void Main( string[] args )
{
using( var db = new TestEntities() )
{
db.EntityBs.Add( new EntityB()
{
EntityBId = 78
} );
db.SaveChanges();
Task.WaitAll( Test( db ) );
}
var input = Console.ReadLine();
}
static Task<List<EntityB>> GetEntityBsAsync( TestEntities db )
{
return db.EntityBs.ToListAsync();
}
static async Task Test( TestEntities db )
{
var a0 = await GetEntityBsAsync( db );
var a1 = await GetEntityBsAsync( db );
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3407 次 |
| 最近记录: |