在ASP.Net Core应用程序启动期间运行异步代码

16

将函数ConfigureServices的签名更改为异步(原本它只是一个void同步函数且应用程序运行得非常好),我遇到了以下错误:

无法找到所需的服务。请在应用程序启动代码中的ConfigureServices(...)中调用IServiceCollection.AddAuthorization来添加所有所需的服务。

下面是我的ConfigureServices函数的代码。

// This method gets called by the runtime. Use this method to add services to the container.
public async Task ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();

    // Create the necessary Cosmos DB infrastructure
    await CreateDatabaseAsync();
    await CreateContainerAsync();
}

ConfigureServices 在运行时会被自动调用。


有可能使用IHostedService https://dev59.com/olkT5IYBdhLWcg3wG7_4#64118183 - oleksa
1个回答

33

您不能仅更改签名,必须将其设置为void才能被框架调用。

现在当您将其更改为Task时,这意味着框架找不到它,因此根本不会调用它。

这里有一个GitHub问题:https://github.com/dotnet/aspnetcore/issues/5897

尽管这很棘手...

5.0没有进展,我们不知道如何在不阻塞或破坏更改的情况下完成此操作。可能可以将过滤器分为不重叠的两个阶段运行。

根据您的评论更新:

如果您想在启动期间异步运行某些内容,我通常会像这样做:

我创建一个像这样的接口:

public interface IStartupTask
{
     Task Execute();
}

那么可以像这样进行示例实现

public class CreateDatabaseStartupTask : IStartupTask
{
    public async Task Execute()
    {
          // My logic here
          // await CreateDatabaseAsync();
    }
}

然后在我的Program.cs文件中

public static async Task Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();
    
    // Resolve the StartupTasks from the ServiceProvider
    var startupTasks = host.Services.GetServices<IStartupTask>();
    
    // Run the StartupTasks
    foreach(var startupTask in startupTasks)
    {
        await startupTask.Execute();
    }
    await host.RunAsync();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });
}

我的创业公司

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<IStartupTask, CreateDatabaseStartupTask>();
    }
}

所以重要的事情是:

  1. 注册您的StartupTasks
  2. 构建主机
  3. 解决StartupTasks
  4. 运行StartupTasks
  5. 启动主机

那么我该如何在启动时调用异步函数(CreateDatabaseAsync和CreateContainerAsync)? - Henry Zhu
更新了我的回答,并附上了示例。 - JOSEFtw
1
这太棒了 - 我一定会尝试一下。 - Alex
1
只有一个问题。 如何在服务中进行 DI DbContext? - Jaztingo
这在https://andrewlock.net/running-async-tasks-on-app-startup-in-asp-net-core-part-2/中有详细描述。 - proteus

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