Поддержание работоспособности параллельной задачи в ASP.Net Core Web API - PullRequest
1 голос
/ 26 октября 2019

У меня есть ASP.Net Core Web API, использующий EF Core для взаимодействия с базой данных. Жизненный цикл DBContext управляется для каждого контейнера внедрения зависимостей в классе запуска:

services.AddDbContext<MyDbContext>(opts =>
                opts.UseSqlServer(Configuration.GetConnectionString("MyDbConnectionString")));

В веб-методе GET я хочу использовать фоновую задачу, которая обрабатывает и сохраняет данные в базе данных, но DBContext удаляется перед его использованием. для сохранения данных.

public class MyController : Controller
{
    private readonly MyDbContext _context;

    public MyController(MyDbContext context)
    {
        _context = context;
    }

    [HttpGet("test")]
    public async Task<IActionResult> Test(int id)
    {
        var item = _context.Items.SingleOrDefault(i => i.Id == id);

        Task t = new Task(() => SaveAsync(_context));
        t.Start();

        return Ok(item);
    }

    private void SaveAsync(MyDbContext context)
    {
        //processing something for a while
        context.SaveChanges();
    }

}

Проблема состоит в том, что объект _context был удален контейнером DI, и я получаю ошибку ниже: System.ObjectDisposedException: 'Невозможно получить доступ к удаленному объекту. Распространенной причиной этой ошибки является удаление контекста, который был разрешен путем внедрения зависимости, а затем попытка использовать тот же экземпляр контекста в другом месте вашего приложения. Это может произойти, если вы вызываете Dispose () для контекста или заключаете контекст в оператор using. Если вы используете внедрение зависимостей, вы должны позволить контейнеру внедрения зависимостей избавиться от экземпляров контекста. '

Ошибка совершенно ясна для меня, но знаете ли вы, как сохранить _context в фоновой задаче?

1 Ответ

1 голос
/ 26 октября 2019

Если вы хотите сделать что-то подобное, я рекомендую вам изучить Фоновые задачи с размещенными службами в ASP.NET Core . Однако, чтобы обойти эту ошибку, попробуйте использовать RegisterForDispose . Существует также асинхронная версия.

HttpContext.Response.RegisterForDispose(_context);
...