gpt4 book ai didi

c# - 是什么导致 Winforms 默默地丢弃未处理的异常(没有 try/Catches)?

转载 作者:太空狗 更新时间:2023-10-30 01:09:26 26 4
gpt4 key购买 nike

我正在为我的 winforms 控件添加新功能,其中一部分要求曾经总是使用的变量现在是可选的(如果它为 null,则从第二个来源获取数据)。我做了一些更改并运行了我的表单,却发现什么也没发生,即使是以前可以使用的功能。困惑的是,我逐步查看了代码,发现我的 Winforms 用户控件在遇到我的变量时抛出 NullReferenceException,但在 UI 中没有抛出任何错误。

我的设置是我有一个带有组合框的 UserControl。当用户更改该组合框时,它会在第一个控件具有的面板中加载辅助 UserControl。第二个控件是抛出异常的控件。

代码路径如下:

    private void cmbActionType_SelectedIndexChanged(object sender, EventArgs e)
{
if (_loading)
return;

// ActionType was changed, update the action.ActionType value
if (cmbActionType.SelectedItem != null)
{
if (cmbActionType.SelectedItem.ToString() == SETVALUE_OPTION)
_action.ActionType = ActionTypes.SetValue;
else if (cmbActionType.SelectedItem.ToString() == CHECKVALUE_OPTION)
_action.ActionType = ActionTypes.CheckValue;
else
_action.ActionType = ActionTypes.CustomAction;
}

RefreshActionPanel();
_editor.DataModified();
}

private void RefreshActionPanel()
{
// Control defaults
AnchorStyles styles = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
UserControl subControl = null;

// Clear the currently active control
pnlActionDetails.Controls.Clear();

// Determine what type of control to load in the panel
if (cmbActionType.SelectedItem != null && cmbCaseType.SelectedItem != null)
{
// SetValue or CheckValue actions
if (cmbActionType.SelectedItem.ToString() == CHECKVALUE_OPTION || cmbActionType.SelectedItem.ToString() == SETVALUE_OPTION)
{
if (_caseTypeMap.ContainsKey(cmbCaseType.SelectedItem.ToString()))
subControl = new SetCheckActionControl(_action, _editor, _caseTypeMap[cmbCaseType.SelectedItem.ToString()]);
}

// CustomAction action type
else
{
// Check if the requested case is a type or defined in a script
if (_caseTypeMap.ContainsKey(cmbCaseType.SelectedItem.ToString()))
{
subControl = new CustomActionControl(_action, _editor, _caseTypeMap[cmbCaseType.SelectedItem.ToString()]);
}

else if (_editor.ScriptDefinitions.Any(x => x.CaseName == cmbCaseType.SelectedItem.ToString()))
{
var definitions = _editor.ScriptDefinitions.Where(x => x.CaseName == cmbCaseType.SelectedItem.ToString()).ToList();
subControl = new CustomActionControl(_action, _editor, definitions);
}
}
}

if (subControl != null)
{
subControl.Anchor = styles;
subControl.Height = pnlActionDetails.Height;
subControl.Width = pnlActionDetails.Width;
pnlActionDetails.Controls.Add(subControl);
}
}

public CustomActionControl(TestAction action, fmEditor editor, IList<TcScriptDefinition> scriptDefinitions) : base(action, editor)
{
_loading = true;
InitializeComponent();

_scriptDefinitions = scriptDefinitions;

PopulateActionList();
SetupDataGrid();

_loading = false;
}

private void SetupDataGrid()
{
// Clear the current contents of the datagrid
grdParameters.Rows.Clear();

if (cmbAction.SelectedItem == null)
return;

// Retrieve the action code from the drop down
string actionCode = cmbAction.SelectedValue.ToString();

// Check if any paramters are available for this action
if (!_availableActionParameters.ContainsKey(actionCode))
return;

// Add a new row for each parameter available for this action
foreach (string param in _availableActionParameters[actionCode])
{
string display = param;

// Determine if the parameter has a display string
if (_formInstance.CodeDisplayMap.ContainsCode(param))
display = _formInstance.CodeDisplayMap.GetDisplayStringFromCode(param);

// Create the array for the row, with an empty string as the current value
string[] row = { display, string.Empty };

// Check if the current action uses this action code.
// If so, retrieve the value for this parameter and use it in the row
// Note: Case-INsensitive comparison must be performed here
if (_action.Attributes["action"].Equals(actionCode, StringComparison.CurrentCultureIgnoreCase))
if (_action.Attributes.ContainsKey(param))
row[1] = _action.Attributes[param];

grdParameters.Rows.Add(row);
}
}

NullReferenceException 来自调用 _formInstanceSetupDataGrid() 方法。但是,通常当应用程序遇到未处理的异常时,JIT 系统会抛出一条错误消息(如您​​所见,除非我是瞎子,否则不会使用 try/catch 语句)。

为什么我的 winforms 应用程序没有显示异常发生的迹象。我宁愿出现未处理的异常消息,也不愿什么都没有发生,因为这会让用户更难知道出现了关键问题(而不是它不响应他们的命令)


编辑:澄清一下,因为似乎有些困惑,我不关心在调试时在 visual studio 中打破这个异常。事实是应用程序不应该隐藏未处理的异常,我的应用程序应该崩溃(或者更确切地说显示发生未处理异常的 JIT 消息),即使不在 visual studio 之外的 Debug模式下也是如此。

这不是调试时间问题,而是生产运行时间问题。例如,如果此代码抛出 OutOfMemoryException,我需要它不会被静默忽略。现在它被忽略了。

最佳答案

从 Visual Studio 的菜单栏转到 Debug->Exceptions...(Ctrl-D, E,如果您使用的是默认快捷方式)并选中该框对于 Common Language Runtime Exceptions 下的 Thrown。这将导致您的程序在出现异常时中断,即使它们在 try/catch block 中也是如此。然后,您可以向前迈出一步,查看代码跳转到下一条指令的位置。这应该会将您带到隐藏异常的 catch block 。

它可能会跳转到 .NET 代码中,您可以转到 Debug->Options and Settings.. 并打开 Enable .NET framework Source Stepping 看看它跳进了什么。


这是一个捕获代码中未处理的异常的例子

static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Form1());
MessageBox.Show("0");
}

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show("1");

}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{

throw new ArgumentNullException();
}
}

点击按钮出现1,之后程序应该仍然运行。

然而,正如我在上一条评论中所说,首先检查是否在 Debug->Exceptions 中选中了 user-unhandeled(可能取消选中并重新选中)它可能会解决您最初的问题..

关于c# - 是什么导致 Winforms 默默地丢弃未处理的异常(没有 try/Catches)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6832338/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com