【发布时间】:2015-04-14 13:11:17
【问题描述】:
我长期使用以下方法(大约 5 年):
在控制器中创建一个初始化 XXXEntities 的大类,并使用 DB 为每个动作创建每个方法。示例:
public class DBRepository
{
private MyEntities _dbContext;
public DBRepository()
{
_dbContext = new MyEntities();
}
public NewsItem NewsItem(int ID)
{
var q = from i in _dbContext.News where i.ID == ID select new NewsItem() { ID = i.ID, FullText = i.FullText, Time = i.Time, Topic = i.Topic };
return q.FirstOrDefault();
}
public List<Screenshot> LastPublicScreenshots()
{
var q = from i in _dbContext.Screenshots where i.isPublic == true && i.ScreenshotStatus.Status == ScreenshotStatusKeys.LIVE orderby i.dateTimeServer descending select i;
return q.Take(5).ToList();
}
public void SetPublicScreenshot(string filename, bool val)
{
var screenshot = Get<Screenshot>(p => p.filename == filename);
if (screenshot != null)
{
screenshot.isPublic = val;
_dbContext.SaveChanges();
}
}
public void SomeMethod()
{
SomeEntity1 s1 = new SomeEntity1() { field1="fff", field2="aaa" };
_dbContext.SomeEntity1.Add(s1);
SomeEntity2 s2 = new SomeEntity2() { SE1 = s1 };
_dbContext.SomeEntity1.Add(s2);
_dbContext.SaveChanges();
}
还有一些外部代码创建 DBRepository 对象并调用方法。 它工作得很好。但是现在异步操作进来了。所以,如果我使用类似的代码
public async void AddStatSimplePageAsync(string IPAddress, string login, string txt)
{
DateTime dateAdded2MinsAgo = DateTime.Now.AddMinutes(-2);
if ((from i in _dbContext.StatSimplePages where i.page == txt && i.dateAdded > dateAdded2MinsAgo select i).Count() == 0)
{
StatSimplePage item = new StatSimplePage() { IPAddress = IPAddress, login = login, page = txt, dateAdded = DateTime.Now };
_dbContext.StatSimplePages.Add(item);
await _dbContext.SaveChangesAsync();
}
}
可能是这样一种情况,下一个代码将在 SaveChanged 完成之前执行,并且会在 _dbContext 中添加一个实体,在某些操作之前不应保存该实体。比如一些代码:
DBRepository _rep = new DBRepository();
_rep.AddStatSimplePageAsync("A", "b", "c");
_rep.SomeMethod();
我担心,SaveChanged 会在一行之后被调用
_dbContext.SomeEntity1.Add(s1);
但之前
_dbContext.SomeEntity2.Add(s2);
(即这两个动作是原子操作)
我说的对吗?我的方法现在错了吗?应该使用哪种方法?
PS。据我了解,将是以下堆栈:
1. calling AddStatSimplePageAsync
2. start calling await _dbContext.SaveChangesAsync(); inside AddStatSimplePageAsync
3. start calling SomeMethod(), _dbContext.SaveChangesAsync() in AddStatSimplePageAsync is executing in another (child) thread.
4. complete _dbContext.SaveChangesAsync() in child thread. Main thread is executing something in SomeMethod()
【问题讨论】:
-
我不确定我是否收到了您的问题。看起来您担心异步操作,如果在另一个请求到来时未完成,可能会给您的代码分配带来一些问题?你能详细说明一下吗?
-
向主要问题添加了详细信息
-
这不是异步/等待操作的工作方式。 Async/await 不会转到另一个需要
awaited函数调用结果的函数。您当前的方法对我来说似乎很好,要进一步阅读,请查看 MSDN,特别是我在这里链接到的部分 - msdn.microsoft.com/en-us/library/… -
另外,您的示例编辑,您并没有等待您的
AdStatSimplePageAsync方法,因此,它将正常运行(同步)。 -
据我了解,方法 AddStatSimplePageAsync 在等待 _dbContext.SaveChangesAsync();正在调用,但在完成之前。看我问题的最后,我补充了一些东西
标签: c# asp.net-mvc entity-framework async-await