gpt4 book ai didi

c# - 在上一个异步操作完成之前,第二个操作在此上下文中启动

转载 作者:可可西里 更新时间:2023-11-01 03:13:55 24 4
gpt4 key购买 nike

留言:

"System.NotSupportedException was unhandled
Message: An unhandled exception of type 'System.NotSupportedException' occurred in mscorlib.dll
Additional information: A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe."

代码:

public async Task<IEnumerable<UserLangDTO>> ImportLang(int userId)
{
var userLangs = new List<UserLangDTO>();
using (FirstContext ctx = new FirstContext())
{
if (await (ctx.UserLang.AnyAsync(u => u.UserId == userId)) == false)
//some exception here

userLangs = await ctx.UserLang.AsNoTracking()
.Where(ul => ul.UserId == userId)
.Join(ctx.Language,
u => u.LangID,
l => l.LangID,
(u, l) => new { u, l })
.Join(ctx.Level,
ul => ul.u.LevelID,
le => le.LevelID,
(ul, le) => new { ul, le })
.Select(r => new UserLangDTO
{
UserId = r.ul.u.UserId,
Language = r.ul.l.Language,
Level = r.le.Level,
}).ToListAsync().ConfigureAwait(false);

}
using (SecondContext ctx = new SecondContext())
{
if ( await (ctx.UserLangs.AnyAsync(u => u.UserId == userId)) == true && userLangs.Any())
ctx.UserLangs.RemoveRange(ctx.UserLangs.Where(u => u.UserId == userId));
if (await hasUserLangs && userLangs.Any())
{
userLangs.ForEach(async l =>
{
var userLanguage = new UserLang();
userLanguage.UserId = userId;
userLanguage.LanguageId = await ctx.Languages.AsNoTracking()
.Where(la => la.NameEn == l.Language)
.Select(la => la.Id).FirstOrDefaultAsync().ConfigureAwait(false);
userLanguage.LevelId = await ctx.Levels.AsNoTracking()
.Where(la => la.NameEn == l.Language)
.Select(la => la.Id).FirstOrDefaultAsync().ConfigureAwait(false);

ctx.UserLangs.Add(userLanguage);
});
}
await ctx.SaveChangesAsync().ConfigureAwait(false);
}
return userLangs;
}

我的尝试:

我不确定我做错了什么,我尝试了不同的东西,比如:

1.

await Task.Run(() => Parallel.ForEach(strings, s =>
{
    DoSomething(s);
}));

2.

var tasks = userLangs.Select(async l =>
{
//rest of the code here
}
await Task.WhenAll(tasks);

3.

var tasks = userLangs.Select(async l =>
{
//rest of the code here
}
await Task.WhenAll(tasks);

await ctx.SaveChangesAsync().ConfigureAwait(false);
  1. 我现在不记得的其他试错尝试

我做错了什么?

最佳答案

这是你的问题:

userLangs.ForEach(async

这是在创建一个 async void 方法,因为 ForEach 不理解异步委托(delegate)。所以ForEach的主体会并发运行,Entity Framework不支持并发异步访问。

ForEach 更改为 foreach,您应该会很好:

foreach (var l in userLangs)
{
var userLanguage = new UserLang();
userLanguage.UserId = userId;
userLanguage.LanguageId = await ...
}

有关详细信息,请参阅我的 Async Best Practices article 中的“避免异步无效”指南.

关于c# - 在上一个异步操作完成之前,第二个操作在此上下文中启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40363807/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com