English 中文(简体)
Concurrency Issue with DbContext in ASP. NET 核心应用
原标题:Concurrency Issue with DbContext in ASP.NET Core Application

在申请中,<代码>HomeController在使用背景联合书刊的书章上操作了一部法律,以履行OCR(签字特性确认)。

<代码>HomeController的定义如下:

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private readonly BookStoreContext _context;
    private readonly IBackgroundJobService _jobService;

    public HomeController(ILogger<HomeController> logger, BookStoreContext context, IBackgroundJobService jobService)
    {
        _context = context;
        _logger = logger;
        _jobService = jobService;
    }

    public async Task<IActionResult> RunOCR()
    {
        await _jobService.RunOCRJob();
        return View();
    }
}

www.un.org/Depts/DGACM/index_french.htm 班级负责内部监督事务办公室和数据库业务:

public class BackgroundJobService : IBackgroundJobService
{
    private readonly ILogger<BackgroundJobService> _logger;
    private readonly BookStoreContext _context;
    private readonly IFileHandleService _fileService;
    private readonly IOcrService _ocrService;

    public BackgroundJobService(BookStoreContext context, IOcrService ocrService, ILogger<BackgroundJobService> logger)
    {
        _logger = logger;
        _context = context;
        _ocrService = ocrService;
    }

    public async Task RunOCRJob()
    {
        _logger.LogInformation("Starting OCR job.");

        var toRunOCR = await _context.BookChapters
            .Include(b => b.Book)
            .Include(t => t.Content)
            .Where(c => !c.IsOcrRequested && c.Book.ChapterExtracted)
            .OrderBy(o => o.Id)
            .Take(20)
            .ToListAsync();

        var ocrTasks = new List<Task>();

        foreach (var chapter in toRunOCR)
        {
            var bookChapterVm = new ChapterOCRViewModel(chapter.Id, chapter.Path);
            ocrTasks.Add(RunBackgroundJob(bookChapterVm));
        }

        await Task.WhenAll(ocrTasks);

        await _context.SaveChangesAsync();

        _logger.LogInformation("OCR job completed.");
    }

    public async Task RunBackgroundJob(ChapterOCRViewModel chapter)
    {
        try
        {
            var chapterFilePath = _fileService.GetChapterFilePath(chapter.Path);
            var pageContent = await _ocrService.ReadTextFromPdfAsync(chapterFilePath);

            var chapterEntity = await _context.BookChapters
                .Include(cont => cont.Content)
                .FirstOrDefaultAsync(c => c.Id == chapter.Id);

            if (chapterEntity.Content == null)
                chapterEntity.Content = new ChapterContent();

            chapterEntity.Content.Text = pageContent;
            chapterEntity.OcrAt = DateTime.UtcNow;
            chapterEntity.Status = StatusEnum.ScheduledIndex;
            chapterEntity.IsOcrRequested = true;

            _logger.LogInformation($"OCR for Chapter ID: {chapter.Id} completed successfully.");
        }
        catch (Exception ex)
        {
            _logger.LogError($"Error while OCR for Chapter ID: {chapter.Id}. Error message: {ex.Message}");
        }
    }
}

我面临的问题是,当我执行《RunOCR行动》时,我遇到以下错误:

fail: Microsoft.EntityFrameworkCore.Query[10100] An exception occurred while iterating over the results of a query for context type OTTT.Db.BookStoreContext . System.InvalidOperationException: A second operation was started on this context instance before a previous operation was completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.

我使用了<代码>Take查询,因为查询只给我20个记录,而处理20个记录时,只有2个或3个错误。

我的理解是,这一错误与DbContext的一致意见有关,我怀疑,这可能是利用《书刊》同文的多重背景任务造成的。 我一直在使用依赖性注射来管理DbContext的寿命,但问题依然存在。

I am stuck on how to resolve this concurrency issue and safely use DbContext within my background job.

Edit used the db context factory but got the same error:

public class BackgroundJobService : IBackgroundJobService
{
    private readonly IServiceProvider _serviceProvider;
//...
    public BackgroundJobService(IDbContextFactory contextFactory, IFileHandleService fileService, BookStoreContext context, IOcrService ocrService,
    ILogger<BackgroundJobService> logger, IServiceProvider serviceProvider)
    {
        _logger = logger;
        _context = context;
        _fileService = fileService;
        _ocrService = ocrService;
        _contextFactory = contextFactory;
    }
    public async Task RunOCRJob()
    {
        _logger.LogInformation("Starting OCR job.");

        using (var context = _contextFactory.Create())
        {
            var toRunOCR = await context.BookChapters
                                .Include(b => b.Book)
                                .Include(t => t.Content)
                                .Where(c => !c.IsOcrRequested && c.Book.ChapterExtracted)
                                .OrderBy(o => o.Id)
                                .Take(20)
                                .ToListAsync();
    //...
            await context.SaveChangesAsync();
        }

        _logger.LogInformation("OCR job completed.");
    }

    public async Task RunBackgroundJob(BookStoreContext context, ChapterOCRViewModel chapter)
    {
        try
        {
    // removed code

            var chapterEntity = await context.BookChapters
                .Include(cont => cont.Content)
                .FirstOrDefaultAsync(c => c.Id == chapter.Id);
    
    // removed code


        }
        catch (Exception ex)
        {
            _logger.LogError($"Error while OCR for Chapter ID: {chapter.Id}. Error message: {ex.Message}");
        }
    }
问题回答




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签