我有一个应用程序,设计为在 24/7 服务器上运行。本地测试一切正常且符合预期。部署到 Windows Server 2012 R2 - 每当主任务(线程)启动时,我都会遇到异常。
在服务器上我显然没有 Visual-Studio,所以我无法调试 ig。我刚刚收到一个丑陋的 Windows 对话框,指出“{ApplicationName} 已停止工作。”。
在事件查看器中我找到了一个条目,指示错误的位置。
事件日志说:
Application: MyApplicationBackend.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.FileNotFoundException
Stack:
at Application.Name.SomeClass..ctor()
at Application.Name.SomeThread()
at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart()
嗯,在 SomeClass 的构造函数中没有什么重要的事情发生 - 只是一个 mysql 数据库连接,如下所示,(其中 cfg. 是一个单例,保存配置值):
//Connecto to server.
String connectionString = "server=" + cfg.DatabaseServer + ";user=" + cfg.DatabaseUser + ";database=" + cfg.DatabaseName + ";port=" + cfg.DatabasePort + ";password=" + cfg.DatabasePassword + ";";
mysqlConnection = new MySqlConnection(connectionString);
- 已安装 MySQL 连接器 .Net 6.8.3
- 代码将连接到远程数据库(本地网络)
- 代码在我的本地机器上完美运行。 (同一网络)
这提出了 2 个问题:
1.) 我可以(如果,如何?)处理出现在主线程任何级别的嵌套线程中的异常吗?
2.) 未找到的文件可能是什么类型(关于这两行代码)?本地工作正常(源位于网络共享上),但是当从我的服务器执行时,我收到此异常(使用来自相同网络共享的相同可执行文件)
<小时/>只是使用了一些 MessageBox 来调试这些东西......最终它看起来像下面这样:
public class class1{
private void SomeThread(){
MessageBox.Show("before con");
DbCon dc = new DbCon();
MessageBox.Show("after con");
}
}
和
public class DbCon{
public DbCon(){
MessageBox.Show("inside");
String connectionString = "server=" + cfg.DatabaseServer + ";user=" + cfg.DatabaseUser + ";database=" + cfg.DatabaseName + ";port=" + cfg.DatabasePort + ";password=" + cfg.DatabasePassword + ";";
mysqlConnection = new MySqlConnection(connectionString);
}
}
我收到“before con”消息 - 然后抛出异常...就像它只是找不到 DbCon
-Class - 但这是可执行文件的一部分 - 并且无法触发文件未找到异常
??!! (并且可以在本地计算机上运行:-( ) ...
最佳答案
1) 是的,您可以 - 尽管强烈建议不要使用它,但您可以随时通过 Hook FirstChanceException Event 捕获任何异常。 .
AppDomain.Current.FirstChanceException += (sender, e) => { ... };
请注意,这也会引发随后处理的异常,包括 .NET 在后台处理的异常,并且可能会稍微减慢您的应用程序速度。通常不推荐这样做,但它绝对会捕获应用程序托管代码中抛出的所有内容,无论是在程序集内部还是外部,这使得调试起来绝对出色。
编辑:如果您希望尽可能轻松地附加它,请将 Main 放入静态类中,并将事件 Hook 放入静态构造函数中。这迫使它尽早发生,它可以抢占 DLL 加载。
2) 假设您从文件加载配置,则有多种原因导致找不到文件。
- 如果您在服务器上执行,请确保程序以管理员身份运行或具有访问文件系统所需的权限。这是网络共享上的常见问题
- 确保您没有尝试使用本地路径(例如“C:\ProgramData”或“%ProgramData%”)引用该文件,因为这些路径将查找执行计算机的 C 驱动器。
- 如果您使用 GAC 中的任何 DLL,请将它们复制到输出文件夹中 - 如果服务器未加载文件或具有不同版本,这可能会导致异常(尽管通常是 DllNotFoundException)已加载。
如果您有访问权限,还可以尝试远程连接到服务器并在本地进行调试,因为这可以帮助揭示实际部署环境的问题。还有办法debug on a remote machine这可能对您的情况有用。
关于C# 捕获 "Main-Thread"上的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24687072/