【问题标题】:Timeouts with deployed code but not during debugging已部署代码但在调试期间没有超时
【发布时间】:2011-08-23 16:03:01
【问题描述】:

我有一个包含以下相关项目的 C# winforms 应用程序:

  • VS2010 SP1,.NET 3.5
  • Fluent NHibernate 1.0(使用 NH 3.0,也许这是问题的一部分)
  • 使用 ClickOnce 部署
  • SQL Server 2008 R2 数据库

我已经在我的机器上安装了已部署的副本(通过 ClickOnce),并且正在通过 VS2010 调试器并排运行另一个副本。它是相同的代码库。我昨天刚刚发布,发布后没有更改任何代码。

在同一台机器上(同样,并排运行),指向同一个 SQL Server 实例,我的应用程序的部署副本尝试写入数据库时​​超时。通过调试器开始的副本写得很好。每次都是可重复的。

在现实世界中,只有几个人报告超时。他们在同一个部门,就在大楼的同一个地方。他们是唯一的(好吧,我知道)。我正在使用相同的 SQL 实例来调试他们正在使用的这个。

所有文件(.pdb 除外)都包含在解决方案中所有项目的部署中。

这是外部异常的堆栈跟踪(我还没有任何内部异常的堆栈跟踪):

Stack Trace:
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
   at NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)
   at NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session)
   at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
   at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
   at NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) 

什么会导致一个超时但另一个不会?在同一台机器上,同时运行(甚至一个接一个)。我什至从 build\bin\ 文件夹本地运行它,没有超时,就像通过调试器一样。只有部署的副本会产生超时。

更新:
我已经能够为生产环境捕获 SQL Profiler 跟踪,并且除了对数据库的实际写入之外,一切都进入了 SQL,这确实发生在后台线程上。执行保存的方法(可以由插入和/或更新的组合组成)被调用,正如我在跟踪中看到的那样,该方法中的查询在保存完成之前运行。我现在正在捕获整个异常堆栈。

更新 2:
我终于在调试器中重现了错误,并隔离了抛出异常的位置。我上面提到的在保存之前发生的查询导致超时。很好,现在我可以解决这个问题并继续前进。

但问题仍然存在:为什么它是在运行发布代码的进程中引发的,而不是在运行完全相同代码库的调试进程中。

【问题讨论】:

  • 也许您部署的版本指向另一个数据库。能否在访问数据库之前添加代码来显示连接字符串(例如 MessageBox.Show())?
  • @Adi 我在应用程序中有一个关于屏幕,显示所有连接信息。都是一样的,我验证了...
  • @squillman 嗯,我见过很多“奇怪”的事情,最不可能的事情实际上正在发生......所以只要它是一种简单的方法,我会在之前实现那个消息框访问数据库。不过我不想逼你……
  • 您是否尝试过使用编译到包中的 DEBUG 变量部署生产版本?

标签: c# winforms deployment timeout


【解决方案1】:

您提到在后台线程中写入数据库,这让我认为这可能是一个并发(多线程)问题。

发布版本通常经过优化,这就是为什么它们的执行可能与调试版本略有不同。这可能导致现有的并发问题成为实际问题。不同的用户有不同的硬件,有不同数量的 CPU 内核(等),同样可能导致执行顺序的细微变化。

所有这一切都是一个疯狂的猜测,没有深入挖掘代码,但多线程往往是这些类型“神秘”问题的罪魁祸首。

【讨论】:

    【解决方案2】:

    当您使用调试模式时,请求超时是无限的,但当您通过发布版本运行它时,情况并非如此。

    如果调用 Web 服务写入数据库,请增加您的请求超时时间,如果没有,请在您的 web.config 或您放置连接字符串的任何位置增加您的数据库连接超时时间。

    问候, 维尼特

    【讨论】:

    • 这不是网络应用程序,它是 winforms。
    【解决方案3】:

    我在连接数据库时遇到了同样的问题。

    我从我的用户那里听说他们有完全相同的异常。 一开始我也不知道怎么回事。

    解决方案是他们没有连接他们的 VPN 密钥

    问候 亚当

    【讨论】:

    • 谢谢,但这都是内部的。
    猜你喜欢
    • 2011-01-08
    • 2010-10-25
    • 2013-11-23
    • 2013-05-12
    • 2023-01-10
    • 1970-01-01
    • 2017-08-31
    • 1970-01-01
    • 2020-05-08
    相关资源
    最近更新 更多