c# - 为什么在完成异步任务之前调用 Dispose?
问题描述
我最近偶然发现了这个奇怪的错误。看起来我的一个对象在我的方法完成所有异步任务之前正在处理。但是让我们来看看。
我有那个为我的数据库播种的异步方法。它在方法中的Startup
类中调用Configure
。
private void InitDatabase(IApplicationBuilder app) {
using (var scope = app.ApplicationServices.CreateScope()) {
var services = scope.ServiceProvider;
try {
var context = services.GetRequiredService<GrabGoContext>();
new DatabaseInitializer().InitializeAsync(context,
services.GetService(typeof(UserManager<User>)) as UserManager<User>,
services.GetService(typeof(SignInManager<User>)) as SignInManager<User>,
services.GetService(typeof(RoleManager<IdentityRole<int>>)) as RoleManager<IdentityRole<int>>,
_logger).Wait();
_logger.LogDebug("Database initialization finished.");
}
catch (Exception ex) {
_logger.LogError(ex, "An error occurred while seeding the database.");
if (Debugger.IsAttached) Debugger.Break();
}
}
}
类中的那个方法DatabaseInitializer
:
public async Task InitializeAsync(GrabGoContext context,
UserManager<User> userManager,
SignInManager<User> signInManager,
RoleManager<IdentityRole<int>> roleManager,
ILogger<Startup> logger) {
if(IsDatabaseInialized) return;
IsDatabaseInialized = true;
await context.Database.EnsureCreatedAsync();
await AddStores(context);
await AddProducts(context);
await AddRoles(roleManager)
.ContinueWith(t => AddRolesToUsers(userManager)); // <- Here throws exception "System.ObjectDisposedException" for object `userManager`
await AddUsers(userManager);
await context.SaveChangesAsync();
}
问题是,如果我使用ContinueWith
链接任务,它会抛出对象System.ObjectDisposedException
。userManager
但我需要使用ContinueWith
,因为我需要Roles
在将用户分配给该角色之前。
我负责添加角色的方法
private async Task AddRoles(RoleManager<IdentityRole<int>> roleManager) {
if (await roleManager.Roles.AnyAsync()) return;
var roles = (List<IdentityRole<int>>) new RolesListExample().GetExamples();
foreach (var role in roles) {
var result = await roleManager.CreateAsync(role);
if(!result.Succeeded) throw new ApplicationException("Erros while adding roles: " +
JsonConvert.SerializeObject(result.Errors));
}
}
private async Task AddRolesToUsers(UserManager<User> userManager) {
var registerModels = (List<RegisterModel>)new RegisterListRequestExample().GetExamples();
foreach(var registerModel in registerModels) {
var user = await userManager.FindByEmailAsync(registerModel.Email);
var result = await userManager.AddToRoleAsync(user, registerModel.Role.ToString());
if(!result.Succeeded)
throw new ApplicationException("Erros while adding roles to user: " +
JsonConvert.SerializeObject(result.Errors));
}
}
还有我的RolesListExample
课:
public class RolesListExample : IExamplesProvider {
/// <inheritdoc />
public object GetExamples() {
var roles = new List<IdentityRole<int>>();
foreach (var availableRole in (AvailableRoles[]) Enum.GetValues(typeof(AvailableRoles))) {
roles.Add(new IdentityRole<int>(availableRole.ToString()));
}
return roles;
}
}
我的问题是:
为什么我的对象在所有任务完成之前就被处理掉了?
我认为这是因为using
. 我也发现了这个问题,但没有为我澄清情况。
@更新
正如@PanagiotisKanavos 所建议的,我删除了using
声明,它解决了我的处置问题。谢谢!
解决方案
您只在等待任务的继续。代替:
await AddRoles(roleManager).ContinueWith(t => AddRolesToUsers(userManager));
...尝试:
var task1 = AddRoles(roleManager);
var task2 = task1.ContinueWith(t => AddRolesToUsers(userManager));
await task1;
await task2;
推荐阅读
- rust - 实现 std Trait 时如何为生命周期参数设置适当的生命周期
- android - 隐式启动 JobIntentService
- boomi - 字符串索引超出范围:-1 in dell boomi
- python - TF服务出错:加载包'@org_tensorflow//tensorflow/python/keras'时出错:
- android - 从列表视图中删除项目
- php - Encrypt 库在使用 php7.2 设置 nginx 时需要 Mcrypt 扩展
- php - 如何在 Laravel 5.6 中使用多个表进行身份验证?
- python - Python CSV Sniffer 检测双引号文本限定符
- java - 是否可以创建具有动态持有人视图高度的可扩展列表视图?
- postgresql - PostgreSQL:refcursor 和门户名称