我长时间使用以下方法(约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()
答案 0 :(得分:2)
好的这次我(想)已经解决了你的问题。
首先,您对SaveChanges
方法进行了两次单独调用,这很奇怪。通常你应该在所有操作结束时尝试使用它然后处理它。
即使是的,你的担忧是对的,但这里需要澄清一些。
遇到async
或await
时,不考虑线程,而是考虑任务,two different concepts。
读一下这篇伟大的article。有一个图像可以解释你的一切。
简单地说,如果您不等待异步方法,您可能会面临后续操作可能会损害&#34;执行第一个。要解决它,只需等待它。