Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Asp.net core:无法访问已释放的对象。此错误的一个常见原因是处理依赖项注入解析的上下文_C#_Entity Framework_Asp.net Core_Dependency Injection - Fatal编程技术网

C# Asp.net core:无法访问已释放的对象。此错误的一个常见原因是处理依赖项注入解析的上下文

C# Asp.net core:无法访问已释放的对象。此错误的一个常见原因是处理依赖项注入解析的上下文,c#,entity-framework,asp.net-core,dependency-injection,C#,Entity Framework,Asp.net Core,Dependency Injection,我正在开发一个web api项目。现在,我在调用端点时遇到了一个问题。我在调用此端点时不会经常出错,例如,如果我每天调用30次,则会出现2次此错误。此端点仅选择数据并异步工作。我尝试了在互联网上找到的所有解决方案,但都不起作用。 错误:无法访问已释放的对象。此错误的一个常见原因是处理通过依赖项注入解析的上下文,然后在应用程序的其他位置尝试使用相同的上下文实例。如果对上下文调用Dispose(),或将上下文包装到using语句中,则可能会发生这种情况。如果您使用的是依赖项注入,那么应该让依赖项注入

我正在开发一个web api项目。现在,我在调用端点时遇到了一个问题。我在调用此端点时不会经常出错,例如,如果我每天调用30次,则会出现2次此错误。此端点仅选择数据并异步工作。我尝试了在互联网上找到的所有解决方案,但都不起作用。 错误:无法访问已释放的对象。此错误的一个常见原因是处理通过依赖项注入解析的上下文,然后在应用程序的其他位置尝试使用相同的上下文实例。如果对上下文调用Dispose(),或将上下文包装到using语句中,则可能会发生这种情况。如果您使用的是依赖项注入,那么应该让依赖项注入容器处理上下文实例

 public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyContext>(options => options.UseMySql(Environment.GetEnvironmentVariable("MY_DB_CONNECTION")), ServiceLifetime.Transient);
services.DIRegisterer();
}

public static IServiceCollection DIRegisterer(this IServiceCollection services)
{
services.AddScoped<MyService>();
}
public void配置服务(IServiceCollection服务)
{
services.AddDbContext(options=>options.UseMySql(Environment.GetEnvironmentVariable(“MY_DB_CONNECTION”))、ServiceLifetime.Transient);
services.diregister();
}
公共静态IServiceCollection diregister(此IServiceCollection服务)
{
services.addScope();
}
注意:我使用的是.NETCore3.1

--更新

从日志中可以看出,ResponseWrapperFilter类导致了此错误。但由于调试时无法捕获此错误,因此找不到原因

    public class ResponseWrapperFilter : IActionFilter, IOrderedFilter
{
    private MYContext myContext;
    private IMemoryCache cache;
    private readonly TimeSpan _defaultCacheTimespan = new TimeSpan(0, 5, 0);
    
    private void FillNavigationProperties(object v, int recursionLevel)
    {
        if (recursionLevel > 2)
            return;
        if (v.GetType().FullName == "System.DateTime" || v.GetType().FullName == "System.String"
            || v.GetType().FullName == "Newtonsoft.Json.Linq.JObject")
            return;
        if (v != null && v.GetType().FullName.StartsWith("System.Collections.Generic.List"))
        {
            foreach (var x in (IList)v)
            {
                foreach (var y in x.GetType().GetProperties())
                {
                    if (x.GetType().FullName == "System.DateTime" || x.GetType().FullName == "System.String"
                        || x.GetType().FullName == "Newtonsoft.Json.Linq.JObject")
                        continue;
                    var prop = y.GetGetMethod().Invoke(x, null);
                    if (prop != null)
                    {
                        FillNavigationProperties(prop, recursionLevel + 1);
                    }
                    else
                    {
                        TryToFillNavigationProperty(x, y);
                    }
                }
            }
        }                      
    }

    private void TryToFillNavigationProperty(object v, PropertyInfo p)
    {                   
        if (p.PropertyType == typeof(Company) || p.PropertyType.IsSubclassOf(typeof(Company)))
        {
            if (v.GetType().GetProperties().Where(_ => _.Name == p.Name + "Id").Any())
            {
                var CompanyId = (ulong)v.GetType().GetProperties().Where(_ => _.Name == p.Name + "Id").First().GetGetMethod().Invoke(v, null);
                var cacheKey = "Company->Id->" + CompanyId.ToString();
                if (cache.TryGetValue(cacheKey, out Company CompanyIdCompany))
                {
                    p.GetSetMethod().Invoke(v, new[] { CompanyIdCompany });
                }
                else
                {
                    CompanyIdCompany = myContext.Set<Company>().Where(_ => _.Id == CompanyId).FirstOrDefault();
                    cache.Set(cacheKey, CompanyIdCompany, _defaultCacheTimespan);
                    **p.GetSetMethod().Invoke(v, new[] { CompanyIdCompany });**
                }
            }
        }
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        if (context.Exception is null)
        {
            myContext = context.HttpContext.RequestServices.GetRequiredService<MYContext>();
            cache = context.HttpContext.RequestServices.GetRequiredService<IMemoryCache>();           
            if (context.Result.GetType() == typeof(ObjectResult))
            {
                object current = ((ObjectResult)context.Result).Value;
                    if (current != null)
                        FillNavigationProperties(current, 0);
                    context.Result = new OkObjectResult(new MYResponse()
                    {
                        Data = current                          
                    });
            }             
        }           
    }
}
public类ResponseWrapperFilter:IActionFilter、IOrderedFilter
{
私有MYContext MYContext;
私有IMemoryCache缓存;
private readonly TimeSpan _defaultCacheTimespan=new TimeSpan(0,5,0);
私有void FillNavigationProperties(对象v,int递归级别)
{
如果(递归级别>2)
返回;
如果(v.GetType().FullName==“System.DateTime”| | v.GetType().FullName==“System.String”
||v.GetType().FullName==“Newtonsoft.Json.Linq.JObject”)
返回;
if(v!=null&&v.GetType().FullName.StartsWith(“System.Collections.Generic.List”))
{
foreach(var x in(IList)v)
{
foreach(x.GetType().GetProperties()中的变量y)
{
如果(x.GetType().FullName==“System.DateTime”| | x.GetType().FullName==“System.String”
||x.GetType().FullName==“Newtonsoft.Json.Linq.JObject”)
继续;
var prop=y.getMethod().Invoke(x,null);
如果(prop!=null)
{
FillNavigationProperties(prop,recursionLevel+1);
}
其他的
{
TryToFillNavigationProperty(x,y);
}
}
}
}                      
}
私有void TryToFillNavigationProperty(对象v,PropertyInfo p)
{                   
如果(p.PropertyType==typeof(Company)| | p.PropertyType.IsSubclassOf(typeof(Company)))
{
if(v.GetType().GetProperties().Where(\u=>\ uName==p.Name+“Id”).Any())
{
var CompanyId=(ulong)v.GetType().GetProperties().Where(\u=>\ uName==p.Name+“Id”).First().getMethod().Invoke(v,null);
var cacheKey=“Company->Id->”+CompanyId.ToString();
if(cache.TryGetValue(cacheKey,out Company Company))
{
p、 GetSetMethod().Invoke(v,new[]{CompanyIdCompany});
}
其他的
{
CompanyIdCompany=myContext.Set().Where(=>u.Id==CompanyId.FirstOrDefault();
Set(cacheKey,CompanyIdCompany,\u defaultCacheTimespan);
**p、 GetSetMethod().Invoke(v,new[]{CompanyIdCompany})**
}
}
}
}
public void OnActionExecuted(ActionExecutedContext上下文)
{
if(context.Exception为null)
{
myContext=context.HttpContext.RequestServices.GetRequiredService();
cache=context.HttpContext.RequestServices.GetRequiredService();
if(context.Result.GetType()==typeof(ObjectResult))
{
对象当前=((ObjectResult)context.Result).Value;
如果(当前!=null)
FillNavigationProperties(当前,0);
context.Result=new-OkObjectResult(new-MYResponse()
{
数据=当前
});
}             
}           
}
}

据我从日志中看到的,粗体行是导致错误的原因(p.GetSetMethod().Invoke(v,new[]{CompanyIdCompany});)

因为这个问题只是偶尔出现,问题的一个可能原因是(意外)与请求操作并行运行的生成后台操作。此并行操作可以访问请求的
DbContext
实例

注意:如果错误在初始成功操作后仍然存在,这将表示
DbContext
被其一个使用者捕获;换言之,这是一个错误

在大多数情况下,后台操作在请求结束之前完成,因此在处置
DbContext
之前完成。但是,在某些情况下,(意外)并行操作会出现延迟,导致它在请求结束后访问
DbContext
,从而在ASP.NET内核处理
DbContext
后访问

这可能是因为您忘记等待一个异步操作。当您忘记等待此类操作时,它将开始并行运行。然而,并行运行这样的代码通常是有益的