Asp.Net Core - 无法访问已处置的对象。对象名称:' System.Net.Sockets.Socket'

时间:2017-02-20 02:11:34

标签: c# mysql sockets asp.net-core .net-core

我在Ubuntu 16.04 LTS上运行的Asp.Net Core 1.1应用程序出现故障。

通常,在一段时间不活动后,当我点击加载网站上的某个地方触发控制器时,网站无法完成加载。我看到控制器在第一个函数15分钟后调用超时,该函数应该从数据库中获取对象(即使在连接字符串中将MySql超时设置为2分钟):

   at Frontend.Repository.WebsiteSettingsRepository.Find(String id, Boolean getRelated)
   at Frontend.Controllers.HomeController.Index()

这是我得到的完整例外:

fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0]
  An unhandled exception has occurred: Connect Timeout expired.
MySql.Data.MySqlClient.MySqlException: Connect Timeout expired. ---> System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.
   at System.Net.Sockets.Socket.BeginConnect(IPAddress address, Int32 port, AsyncCallback requestCallback, Object state)
   at System.Net.Sockets.TcpClient.BeginConnect(IPAddress address, Int32 port, AsyncCallback requestCallback, Object state)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl[TArg1,TArg2](Func`5 beginMethod, Func`2 endFunction, Action`1 endAction, TArg1 arg1, TArg2 arg2, Object state, TaskCreationOptions creationOptions)
   at System.Net.Sockets.TcpClient.ConnectAsync(IPAddress address, Int32 port)
   at MySql.Data.Serialization.MySqlSession.<OpenTcpSocketAsync>d__30.MoveNext()
   --- End of inner exception stack trace ---
   at MySql.Data.Serialization.MySqlSession.<OpenTcpSocketAsync>d__30.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MySql.Data.Serialization.MySqlSession.<ConnectAsync>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MySql.Data.MySqlClient.ConnectionPool.<GetSessionAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MySql.Data.MySqlClient.MySqlConnection.<CreateSessionAsync>d__57.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MySql.Data.MySqlClient.MySqlConnection.<OpenAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MySql.Data.MySqlClient.MySqlConnection.Open()
   at Microsoft.EntityFrameworkCore.Storage.Internal.MySqlRelationalConnection.Open()
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable.Enumerator.BufferlessMoveNext(Boolean buffer)
   at Microsoft.EntityFrameworkCore.Query.QueryMethodProvider.<_ShapedQuery>d__3`1.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.Internal.MySqlQueryingEnumerable`1.MySqlEnumerator.MoveNext()
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
   at lambda_method(Closure , QueryContext )
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass20_0`1.<CompileQueryCore>b__0(QueryContext qc)
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
   at Frontend.Repository.WebsiteSettingsRepository.Find(String id, Boolean getRelated)
   at Frontend.Controllers.HomeController.Index()
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__25.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>d__6.MoveNext()

我使用依赖注入将上下文传递给存储库:

    services.AddDbContext<DatabaseConnector>(options =>
    {
        options.UseMySql(mysqlConfigString);
        options.ConfigureWarnings(warnings => warnings.Throw(CoreEventId.IncludeIgnoredWarning));
    });

在构造函数中:

    public WebsiteSettingsRepository(DatabaseConnector dbContext)
    {
        _db = dbContext;
    }

DatabaseConnector有几个DbSets,例如:

public DbSet<UserModel> Users { get; set; }

据我所知,数据库上下文还使用默认内存缓存来获取临时结果。

数据库仅用于获取前端的详细信息,因此传输的数据量很小(核心数据存储在单独的分布式群集中)。

我怀疑可能会超出池中的连接数,但这会产生不同的错误。不应该有任何连接泄漏,因为永远不会显式打开连接。现在,我认为它可能是特定于操作系统的。大多数时候网站工作正常。有任何想法吗?我已经尝试过扩展虚拟机。

[更新]

控制器的代码,它甚至不是异步的,它只使用多个存储库:

    public IActionResult Index()
    {
        var activity = new CustomLog("HomeController.Index");
        try
        {
            (a couple of non-db lines, the next one throws)
            var newsSpeed = _settingsRepository.Find(WebsiteSetting.NewsSpeed.ToString());
            (...)
            if (newsSpeed != null && newsSpeed.Value != null)
            {
                tableConfig.NewsScrollSpeed = int.Parse(newsSpeed.Value);
            }

            (a lot of similar stuff there...)

            return View(tableConfig);
        }
        catch(Exception e)
        {
            activity.Finish(e);
            throw;
        }
    }

在控制器的构造函数中通过DI设置SettingRepository,如下所示:

private readonly IGenericRepositoryNamed<WebsiteSettingsModel, WebsiteSettingsViewModel> _settingsRepository;

在Startup.cs中创建:

services.AddScoped<IGenericRepositoryNamed<WebsiteSettingsModel, WebsiteSettingsViewModel>, WebsiteSettingsRepository>();

0 个答案:

没有答案