[英]Run async code during startup in a ASP.Net Core application
After changing the signature of the function ConfigureServices
to be asynchronous (originally it was just a void synchronous function and the application worked perfectly fine), I get the following error:在将 function
ConfigureServices
的签名更改为异步后(最初它只是一个 void 同步 function 并且应用程序运行良好),我收到以下错误:
Unable to find the required services.
找不到所需的服务。 Please add all the required services by calling
IServiceCollection.AddAuthorization
inside the call toConfigureServices(...)
in the application startup code.请通过在应用程序启动代码中对
ConfigureServices(...)
的调用中调用IServiceCollection.AddAuthorization
添加所有必需的服务。
Below is the code of my ConfigureServices
function.下面是我的
ConfigureServices
function 的代码。
// 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
is automatically called at runtime. ConfigureServices
在运行时自动调用。
You can't just change the signature, it needs to be void to be called by the framework.您不能只更改签名,它必须是无效的才能被框架调用。
Right now when you changed it to Task it means that the framework can't find it so it will not be called at all.现在,当您将其更改为 Task 时,这意味着框架找不到它,因此根本不会调用它。
There's a GitHub issue regarding this here: https://github.com/dotnet/aspnetcore/issues/5897这里有一个 GitHub 问题: https://github.com/dotnet/aspnetcore/issues/5897
It's quite tricky though...虽然这很棘手......
There's no progress for 5.0 no, we don't know how to do this without blocking or breaking changes.
5.0 没有进展 不,我们不知道如何在不阻止或破坏更改的情况下做到这一点。 It might be possible to run filters in 2 stages that never overlap.
可以在从不重叠的 2 个阶段运行过滤器。
Update based on your comment: If you want to run something async during startup, I usually do like this:根据您的评论进行更新:如果您想在启动期间运行异步操作,我通常会这样做:
I create a interface like this:我创建一个这样的界面:
public interface IStartupTask
{
Task Execute();
}
Then a sample implementation like this然后是这样的示例实现
public class CreateDatabaseStartupTask : IStartupTask
{
public async Task Execute()
{
// My logic here
// await CreateDatabaseAsync();
}
}
Then in my Program.cs然后在我的 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>();
});
}
And my Startup还有我的初创公司
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IStartupTask, CreateDatabaseStartupTask>();
}
}
So the important things are:所以重要的是:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.