标签:生命周期 NetCore sp DbContext 实例 线程 EFCore IServiceProvider 多线程
1、多线程下EFCore的DbContext实例处理
DbContext生命周期默认注入是Scope,每一次请求时创建一个实例,在当前请求的上下文中共用,当请求结束后,释放生命周期,释放数据库链接。若开启多线程,在不同的线程中使用同一个DbContext上下文,则报错如下:System.InvalidOperationException: A second operation was started on this context instance before a previous operation 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.代码演示如下:
解决办法: 在GetAsync中重新创建DbContext(new SecondHandDbContext),不使用请求注入的DbContext:
2、多线程下生命周期已被释放
生命周期为Scope方式,随着请求的结束,实例生命周期也会被释放,因此在多线程下若共享实例,容易出现实例已释放的错误,报错如下:Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it (or one of its parent scopes) has already been disposed.Autofac at Autofac.Core.Lifetime.LifetimeScope.BeginLifetimeScope(Object tag)。通过注入IServiceProvider,
解决办法:
1、在构造函数注入IServiceProvider,应用中通过IServiceProvider的GetService方法获取实例,最终发现IServiceProvider也已被释放,IServiceProvider只是当前请求的实例,该方法失败。
2、从当前应用中获取实例,构造函数注入IHost,通过host获取IServiceProvider:
在线程中通过_sp创建新的生命周期:
using (var sp = _sp.CreateScope())
{
await Task.Delay(5000);
var applyReposity = sp.ServiceProvider.GetRequiredService<IApplyReposity>();
Console.WriteLine($"taskCode:{applyReposity.GetHashCode()},taskThreaId:{Thread.CurrentThread.ManagedThreadId}");
var model = await applyReposity.GetAsync(c => 1 == 1);
sp.Dispose();
}
观察curThreaId与taskThreaId,Task.Run开启了新的线程,与当前主线程线程ID不同,当前请求中注入的IApplyReposity的实例_applyReposity编码是57588670,新线程中开启的新生命周期sp.ServiceProvider中获取的实例编码是2837748;主线程与子线程实例不再相关,解决主线程已释放,子线程获取不到实例的问题。
标签:生命周期,NetCore,sp,DbContext,实例,线程,EFCore,IServiceProvider,多线程 来源: https://www.cnblogs.com/zxsn2014/p/16478922.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。