为什么对话框中的异常不能通过try-catch修复 [英] Why Exception from dialog don't fix by try-catch

查看:55
本文介绍了为什么对话框中的异常不能通过try-catch修复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,



我无法理解为什么一个对话框中的try-catch块没有被捕获异常(在项目VS2005 C ++ WinForms .NET 2.0中)

有一个表格。第二种形式通过按钮调用它。调用ShowDialog方法由try-catch构成(Exception ^ ex)

当您按下Form2中的按钮时,抛出新的异常但不会陷入catch,并导致发布UnhandledException消息。 br />
这种情况​​出现在Debug和Release版本中,但是在VS的逐步调试过程中获得了很好的工作。



我应该做些什么来使这些异常在运行时被捕获?



compil命令行DEBUG:

 / Od / DWIN32/ D_DEBUG/ D_UNICODE/ DUNICODE/ FD / EHa / MDd /Yu\"stdafx.h/Fp\"Debug\\\
ie.pch/ Fo Debug\\/ FdDebug \vc80.pdb/ W3 / nologo / c / Zi / clr:pure / TP / errorReport:prompt / FU ...





compil命令行发布:

 / O2 / GL / DWIN32/ DNDEBUG/ D _UNICODE/ DUNICODE/ FD / EHa / MD /Yu\"stdafx.h/Fp\"Release\\\
ie.pch/ FoRelease\\/ Fd\"Release\vc80.pdb/ W3 / nologo / c / Zi / c lr:pure / TP / errorReport:提示/ FU ...







我的测试App:< br $> b $ b

  //   Form1 .h  
// -------------- ---------------------------------------
#pragma once
#include Form2.h

名称空间 nie {

使用 命名空间系统;
使用 命名空间 System :: ComponentModel;
使用 命名空间 System :: Collections;
使用 命名空间 System :: Windows :: Forms;
使用 命名空间 System :: Data;
使用 命名空间 System :: Drawing;

public ref class Form1: public System :: Windows :: Forms :: Form
{
public
Form1( void
{
InitializeComponent();
dialogForm2 = gcnew Form2;
}

受保护
~Form1()
{
if (components)
{
delete 组件;
}
}
private :System :: Windows :: Forms :: Button ^ buttonCallForm2;
受保护

私人
系统: :ComponentModel :: Container ^ components;

#pragma region Windows窗体设计器生成的代码
void InitializeComponent ( void
{
- > buttonCallForm2 =( gcnew System :: Windows :: Forms :: Button());
- > SuspendLayout();
...

}
#pragma endregion

private :Form2 ^ dialogForm2;
private :System :: Void buttonCallForm2_Click(System :: Object ^ sender,System :: EventArgs ^ e){



try
{
dialogForm2-> ShowDialog ();
MessageBox :: Show(L 退出正常);
}
catch (Exception ^ ex)
{
MessageBox :: Show(ex-> Message); // 无法正常工作
}
catch (...)
{
MessageBox :: Show(L 糟糕); // 不能正常工作
}

}
};
}

// Form2.h
// ------------------------ ------
#pragma once

使用 命名空间系统;
使用 命名空间 System :: ComponentModel;
使用 命名空间 System :: Collections;
使用 命名空间 System :: Windows :: Forms;
使用 命名空间 System :: Data;
使用 命名空间 System :: Drawing;


命名空间 nie {

public ref class Form2: public 系统:: Windows :: Forms :: Form
{
public
Form2( void
{
InitializeComponent();
}

受保护
~Form2()
{
if (components)
{
delete 组件;
}
}
private :System :: Windows :: Forms :: Button ^ buttonEx;
受保护

受保护

private
System :: ComponentModel :: Container ^ components;

#pragma region Windows窗体设计器生成的代码
void InitializeComponent (无效
{
- > buttonEx =( gcnew System :: Windows :: Forms :: Button());
- > SuspendLayout();
...

}
#pragma endregion
private :System :: Void buttonEx_Click(System :: Object ^ sender,System :: EventArgs ^ e){


throw gcnew System :: Exception(L !!! TEST EXCEPTION !!!));

}
};
}





感谢您的帮助!

解决方案

First总而言之,不要尝试在本地捕获异常。只有在您知道确切的异常类型并且需要以特定于语义的方式从异常中恢复时,才应该执行此操作。但基本上,你应该在UI线程的主要偶数循环中捕获所有异常。具体如下:

设置例外模式: http://msdn.microsoft.com/en-us/library/ms157905%28v=vs.110%29.aspx [ ^ ]。

使用系统.Windows.Forms.UnhandledExceptionMode.CatchException

http://msdn.microsoft.com/en-us/library/system.windows.forms.unhandledexceptionmode%28v=vs.110%29.aspx [ ^ ]。



并处理这些异常: http://msdn.microsoft.com/en-us/library/ system.windows.forms.application.threadexception%28v = vs.110%29.aspx [ ^ ]。



另请参阅我过去的答案:

异常详情:System.Runtime .InteropServices.COMException:由于以下错误,检索CLSID为{0006F03A-0000-0000-C000-000000000046}的组件的COM类工厂失败:... [ ^ ],

在类库(dll)中处理异常 [ ^ ],

捕获例外 [ ^ ],

错误记录和屏幕截图。 [ ^ ],

扔。 .then ... rethrowing [ ^ ],

当我运行一个应用程序时,会遇到如何处理这个问题的异常? [ ^ ],

如何制作一个循环停止时滚动条到达底部 [ ^ ],

保持ac#windows form appl尽管存在任何未处理的异常,但仍在运行 [ ^ ]。



你应该更好地理解结构异常处理机制的本质:

C#构造函数中的异常导致调用者分配失败? [ ^ ],

在操作系统中存储.net异常的地方 [ ^ ]。



-SA


dialogForm2 所以需要在 dialogForm2 的try / catch块中捕获。测试确认异常确实被主窗体捕获。

Hello,

I can't understand why the try-catch block in one dialog box are not caught exceptions (in project VS2005 C++ WinForms .NET 2.0)
There is one form. Second form called from it by button. Call the ShowDialog method is framed by try-catch (Exception^ ex)
When you press button in the Form2 the new Exception is thrown but is not falls in catch, and leads to post UnhandledException Message.
This situation present in Debug and Release builds, but
during step-by-step debugging in VS catch wonderful works.

What should I do to make these exceptions are caught in runtime?

compil commandline DEBUG:

/Od /D "WIN32" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /FD /EHa /MDd /Yu"stdafx.h" /Fp"Debug\nie.pch" /Fo"Debug\\" /Fd"Debug\vc80.pdb" /W3 /nologo /c /Zi /clr:pure /TP /errorReport:prompt /FU ...



compil commandline RELEASE:

/O2 /GL /D "WIN32" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /FD /EHa /MD /Yu"stdafx.h" /Fp"Release\nie.pch" /Fo"Release\\" /Fd"Release\vc80.pdb" /W3 /nologo /c /Zi /clr:pure /TP /errorReport:prompt /FU ...




my test App:

//Form1.h
//-----------------------------------------------------
#pragma once
#include "Form2.h"

namespace nie {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;

	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
			InitializeComponent();
			dialogForm2 = gcnew Form2;
		}

	protected:
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::Button^  buttonCallForm2;
	protected: 

	private:
		System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
		void InitializeComponent(void)
		{
			this->buttonCallForm2 = (gcnew System::Windows::Forms::Button());
			this->SuspendLayout();
...

		}
#pragma endregion

	private: Form2^ dialogForm2;
	private: System::Void buttonCallForm2_Click(System::Object^  sender, System::EventArgs^  e) {

				 

				 try
				 {
					dialogForm2->ShowDialog();
					MessageBox::Show(L"exit normal");
				 }
				 catch(Exception^ ex)
				 {
					 MessageBox::Show(ex->Message); // not working properly
				 }
				 catch(...)
				 {
					MessageBox::Show(L"oops"); // not working too
				 }

			 }
	};
}

// Form2.h
// ------------------------------
#pragma once

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;


namespace nie {

	public ref class Form2 : public System::Windows::Forms::Form
	{
	public:
		Form2(void)
		{
			InitializeComponent();
		}

	protected:
		~Form2()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::Button^  buttonEx;
	protected: 

	protected: 

	private:
		System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
		void InitializeComponent(void)
		{
			this->buttonEx = (gcnew System::Windows::Forms::Button());
			this->SuspendLayout();
...

		}
#pragma endregion
	private: System::Void buttonEx_Click(System::Object^  sender, System::EventArgs^  e) {


				 throw (gcnew System::Exception(L"!!! TEST EXCEPTION !!!"));

			 }
	};
}



Thanks for help!

解决方案

First of all, don't try-catch exceptions too locally. It should be done only in cases when you know exact exception type and need to recover from exception in some semantics-specific way. But basically, you should catch all exception on the main even cycle of the UI thread. This is how:
Set exception mode: http://msdn.microsoft.com/en-us/library/ms157905%28v=vs.110%29.aspx[^].
Use System.Windows.Forms.UnhandledExceptionMode.CatchException:
http://msdn.microsoft.com/en-us/library/system.windows.forms.unhandledexceptionmode%28v=vs.110%29.aspx[^].

And handle those exceptions: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception%28v=vs.110%29.aspx[^].

See also my past answers:
Exception Details: System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error:...[^],
Handling exceptions in class library (dll)[^],
Catching an Exception[^],
Error Logging and Screen Shot.[^],
throw . .then ... rethrowing[^],
When i run an application an exception is caught how to handle this?[^],
How do i make a loop that will stop when a scrollbar reaches the bottom[^],
Keep a c# windows form application running despite any unhandled exception[^].

You should better understand the nature of structural exception handling mechanism:
Does Exception in C# Constructor Cause Caller Assignment to Fail?[^],
where was stored .net exceptions in operating system[^].

—SA


The exception occurs in dialogForm2 so it needs to be caught in dialogForm2's try/catch block. A test confirms that the exception does get caught in the main form.


这篇关于为什么对话框中的异常不能通过try-catch修复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆