【发布时间】:2020-06-02 16:07:20
【问题描述】:
我正在编写一个 dll 作为程序的扩展(Windows 10、Visual Studio Professional 2019)。在这个 dll 中,我有一个非常奇怪的行为。场景: 从那时起 dll 的“主”模块(应用程序的回调所在的位置)我打开一个对话框窗口(自己的模块),它在“显示表单”事件中调用第三个模块中的函数。在这第三个模块中,我抛出了一个异常(因为用户取消了一个操作),我想在“主”模块中捕获它。
当我在 VisualStudio 调试器中运行此 dll(调试或发布配置,没有区别)时,应用程序已启动,dll 已加载,上述过程就像一个魅力。 当我在没有 VisualStudio 的情况下运行应用程序时,应用程序已启动,dll 已加载,但在抛出异常后它没有像以前那样被捕获,系统告诉我抛出了异常但没有被捕获。
那么为什么代码可以在 IDE 环境中运行,而不是“独立”?
我唯一能想到的是 .NET 的事件处理代码存在差异。当我在“显示”事件函数中停止时,在调用堆栈中,我看到有对“mscorlib.dll!System.Threading.ExecutionContext”的调用。是否有可能在 VS 之外,dll 处于另一个执行上下文中,从而导致异常被误导?
如果有人可以向我解释这种行为,我将不胜感激。同样,这不是调试或发布版本的问题,而是关于执行环境的问题。
提前致谢,
约尔格
编辑
我希望这可以清除场景:
dll.cs:
// This function is called from the host application
void callback()
{
try
{
Form dialog = new Form();
dialog.ShowDialog();
}
catch (ExceptionType1)
{
...
}
catch (ExceptionType2)
{
...
}
catch
{
...
}
}
dialog.cs
...
// event function for the 'shown' event of Form class
private void SynchronizationDialog_Shown(object sender, EventArgs e)
{
HelperFunction();
}
...
helper.cs
// here the exception is thrown
void HelperFunction()
{
...
if(...)
{
throw new ExceptionType1();
}
...
}
在VS中调试dll时,helper.cs中抛出的异常被catch块捕获,符合预期。 运行应用程序独立调用 dll 时,不会捕获到异常。
编辑
我现在可以提供一个示例项目(VS2020):ExceptionCatchTest
如果你在 VS 中运行它,异常会被捕获,否则不会。
【问题讨论】:
-
实际查看您的代码会更有帮助。你的 try-catch 块在哪里? Form_Shown 事件是通过 Windows 消息触发的,因此在此事件中引发的异常不一定会被构造函数/show 周围的 try-catch 捕获。
-
很遗憾,我无法在此处发布有用的代码,因为这不是我的财产,抱歉。你写道:“不一定会被抓住”。你能解释一下吗?或者给我一个提示在哪里寻找?
-
表单使用 windows 消息来触发事件,例如表单加载、显示、鼠标移动、关闭和关闭。我的猜测是,当您处于调试模式时,Visual Studio 会处理这些消息并封装它们,使您能够在主代码中捕获异常。编译时会删除此封装,因此 try-catch 不再围绕触发异常。如果您可以将异常从表单显示事件移动到表单构造函数(而不是表单加载事件),那么您可以通过在
Form form = new Form()创建表单周围放置一个 try-catch 来捕获异常。 -
@jokey 你不需要上传源代码。只需提供一个重现问题的简单演示即可。
-
@Adam:我想我没有清楚地描述这个场景。我用示例代码发表了一篇新文章。但原则上我认为你是对的。在我的项目中,我通过将 try-catch-blocks 移入表单模块(进入事件函数)解决了这种情况。因此,它必须对 VS 和独立应用程序之间的事件处理有所不同。所以我们有一个有根据的猜测,但我希望能找到能解释背景的人。
标签: c# .net visual-studio exception