web-dev-qa-db-ja.com

コマンドはすでに進行中です

私が開発しているWebアプリのために背景ワーカーを実行しようとしています。私のEFコアプロバイダとしてNPGSQLを使用しています。

説明のために、私は一時的な有効期間を持つDbContextを宣言し、私の​​接続文字列にプールすることを許可しましたが、私がそれをテストしようとするたびに次のエラーが発生します。

NPGSQL.NPGSQLOperationInProgRessException:コマンドがすでに進行中です。[ここに私のクエリ]

そのようにProgramクラスを設定しています。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                // Get the configuration
                IConfiguration config = hostContext.Configuration;

                // DbContext
                services.AddDbContext<MyDbContext>(options => options.UseNpgsql(config.GetConnectionString("PostgreSQLString")), ServiceLifetime.Transient);

                services.AddHostedService<Worker>();
                services.AddScoped<IDTOService, BackgroundDTOService>();
            });
}
 _

それから私のWorkerクラスにつながります

public class Worker : BackgroundService
{
    private Logger logger;

    public Worker(IServiceProvider services, IConfiguration configuration)
    {
        this.Services = services;

        var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
        optionsBuilder.UseNpgsql(configuration.GetConnectionString("PostgreSQLString"));
        var context = new StatPeekContext(optionsBuilder.Options);

        this.logger = new Logger(new LogWriter(context));
    }

    public IServiceProvider Services { get; }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        this.logger.LogInformation("ExecuteAsync in Worker Service is running.");
        await this.DoWork(stoppingToken);
    }

    private async Task DoWork(CancellationToken stoppingToken)
    {
        using (var scope = Services.CreateScope())
        {
            var context = scope.ServiceProvider.GetRequiredService<MyDbContext>();
            var dtoService = scope.ServiceProvider.GetRequiredService<IDTOService>();
            await dtoService.ProcessJSON(stoppingToken);
        }
    }

    public override async Task StopAsync(CancellationToken cancellationToken)
    {
        this.logger.LogInformation("Worker service is stopping.");
        await Task.CompletedTask;
    }
}
 _

これは私のBackGroundDTOServiceにつながります

public class BackgroundDTOService : IDTOService
{
    private int executionCount = 0;
    private Logger logger;
    private MyDbContext context;
    private DbContextOptionsBuilder<MyDbContext> optionsBuilder;

    public BackgroundDTOService(IConfiguration configuration, MyDbContext context)
    {
        this.optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
        this.optionsBuilder.UseNpgsql(configuration.GetConnectionString("PostgreSQLString"));

        this.logger = new Logger(new LogWriter(new MyDbContext(this.optionsBuilder.Options)));

        this.context = context;
    }

    public async Task ProcessJSON(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            this.executionCount++;

            this.logger.LogInformation($"DTO Service is working. Count: {this.executionCount}");

            this.ProcessTeams();

            await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
        }
    }

    public void ProcessTeams()
    {
        // Add Any Franchises that don't exist
        var franchiseDumps = this.context.RequestDumps.Where(rd => rd.Processed == false && rd.DumpType == "leagueteams");
        foreach (RequestDump teamDump in franchiseDumps)
        {
            var league = this.context.Leagues.Include(l => l.Franchises).FirstOrDefault(l => l.Id == teamDump.LeagueID);
            var teams = Jeeves.GetJSONFromKey<List<DTOTeam>>(teamDump.JsonDump, "leagueTeamInfoList");

            foreach (DTOTeam team in teams)
            {
                this.UpdateFranchise(team, league);
            }

            this.logger.LogInformation($"DTO Service Processed League Teams on count {this.executionCount}");
        }

        this.context.SaveChanges();
    }
 _

franchiseDumpsを取得しようとすると、leagueをスナッグする直後にエラーが発生しているようです。

2
jDave1984

この質問に対する答えではありませんが、このページに着陸する人の利点は、同じ接続を使用して2つの非同期呼び出しをしたときにPostgresを扱う私の.NETアプリで同じ例外を示しました。私の愚かな間違いは、最初の非同期呼び出しのためのawaitではありませんでした。

0
Amir Chatrbahr