从数据库种子方法中调用异步方法

3

我正在编写一个MVC 5互联网应用程序,想知道如何在创建数据库时从seed方法调用async方法。

以下是我的代码:

public class ApplicationDbInitializer : CreateDatabaseIfNotExists<ApplicationDbContext> 
{
    protected override void Seed(ApplicationDbContext context) {            
        SetupAdminAndSampleObjectsDatabase();
        base.Seed(context);
    }
}

目前,在调用SetupAdminAndSampleObjectsDatabase方法时,我收到以下错误:

System.NotSupportedException:在上一个异步操作完成之前,在此上下文中启动了第二个操作。使用“await”确保在调用此上下文上的另一个方法之前已完成任何异步操作。任何实例成员都不能保证是线程安全的。

这是该方法的定义:

public async Task SetupAdminAndSampleObjectsDatabase()

我在这个方法中添加了多个对象。

如果使用await关键字调用SetupAdminAndSampleObjectsDatabase方法,那么上述错误是否会被解决?

总之,我该如何从数据库seed方法调用一个async方法?这是可能的吗?

提前致谢。

1个回答

2
您可以选择以下两种方法之一:
1)将Seed方法改为异步方法,并使用await关键字。
protected override async void Seed(ApplicationDbContext context) {            
        await SetupAdminAndSampleObjectsDatabase();
        base.Seed(context);
    }

2) 在异步方法上使用.WaitAndUnwrapException()。

protected override void Seed(ApplicationDbContext context) {            
        SetupAdminAndSampleObjectsDatabase().WaitAndUnwrapException();
        base.Seed(context);
    }

希望这能帮到你!

谢谢。我不知道我可以在重写方法中添加async关键字。 - Simon
只是一点小提示,如果您使用选项1,则需要将 SetupAdminAndSampleObjectsDatabase() 的返回类型更改为 Task(如果原来是 void)或 Task<T>(对于任何原始返回类型 T),以便能够等待它。 - akousmata
1
我不会太乐观地认为我可以选择选项1而不受影响。在这种情况下,调用者将不会等待创建的任务,你可能会遇到类似于以下错误:"异步模块或处理程序在仍有异步操作挂起时完成"。MSDN指出,async void只能用于"使异步事件处理程序成为可能"。 - Paul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接