zoukankan      html  css  js  c++  java
  • BUG记录

    EF通过依赖注入的DbContext,在子线程中使用时报错。

    通过.net core做一个定时任务时,想要通过多线程同时调用一个方法。

    foreach (EnumerationAll config in _enumList)
    {
        _logger.Info($"DDQPicFileUpload->开始处理配置:{config.ToJson()}");
        try
        {
            // 异步执行
            Task UploadPics = new Task(() =>
            {
                try
                {
                    DoUploadDDQPics(config);
                }
                catch (Exception ex)
                {
                    _logger.Error($"DDQPicFileUpload->上传异常:{ex}");
                }
            });
            
            UploadPics.Start();
        }
        catch (Exception ex)
        {
            _logger.Error($"DDQPicFileUpload->上传异常:{ex}");
        }
    }
    View Code

    但是在DoUploadDDQPics方法中读取数据库时,发生异常。

    System.ObjectDisposedException
    HResult=0x80131622
    Message=Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
    ObjectDisposed_ObjectName_Name
    Source=Microsoft.EntityFrameworkCore

    通过报错信息,大致可以推断是在子线程运行时,主线程已经结束了,从而回收了注入的DbContext实例。

    后将方法稍作修改,通过Task.WaitAll()防止主线程提前结束。

    var tasks = new List<Task>();
    foreach (EnumerationAll config in _enumList)
    {
        _logger.Info($"DDQPicFileUpload->开始处理配置:{config.ToJson()}");
        try
        {
            // 异步执行
            Task UploadPics = new Task(() =>
            {
                try
                {
                    DoUploadDDQPics(config);
                }
                catch (Exception ex)
                {
                    _logger.Error($"DDQPicFileUpload->上传异常:{ex}");
                }
            });
            tasks.Add(UploadPics);
            UploadPics.Start();
        }
        catch (Exception ex)
        {
            _logger.Error($"DDQPicFileUpload->上传异常:{ex}");
        }
    }
    // 主进程需要等待子线程全部执行完毕,防止注入的实例被回收。
    Task.WaitAll(tasks.ToArray());
    View Code

    再次运行正常。

  • 相关阅读:
    PHP加速器eAccelerator安装
    WCF
    WCF
    WCF
    前端学习书籍推荐
    问题集录01--java对list列表进行排序
    基础知识:字符编码
    基础知识:if条件、while循环、for循环 相关练习
    基础知识:语言、编程、计算机组成、cpu、存储器
    视图 索引 存储过程
  • 原文地址:https://www.cnblogs.com/ariter/p/11880572.html
Copyright © 2011-2022 走看看