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}"); } }
但是在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());
再次运行正常。