gpt4 book ai didi

c# - 绑定(bind)属性的 Set 方法中的异常未被 Application.ThreadException 事件捕获

转载 作者:行者123 更新时间:2023-11-30 20:48:24 24 4
gpt4 key购买 nike

似乎在属性的 Set 方法中发生的异常不会冒泡到应用程序的 ThreadException 事件。

我们将该事件与 AppDomain.CurrentDomain.UnhandledException 事件一起使用,以捕获应用程序中发生的任何意外事故。异常详细信息将写入日志,以便我们的支持和开发团队可以更好地评估问题。遗憾的是,在这种特殊情况下,Catch All 似乎达不到要求。

StackOverflow上有几个类似的问题,但是没有回答解决全局异常处理不捕获异常的问题。我已经知道我们可以修复它,所以不会发生异常。我们可以为每个 setter 添加一个 TryCatch block 。我们可以将 BindingComplete 事件添加到每个数据绑定(bind)并以这种方式获取异常。但所有这些都违背了全局异常处理的目的,而全局异常处理在任何其他情况下都能完美运行。

要重现该问题,只需创建一个带有文本框的表单,将文本框绑定(bind)到一个属性并在该属性的 set 方法中抛出异常。将 ThreadException 和 UnhandledException 事件添加到 program.cs。运行程序并在文本框中键入以触发异常。调试器将中断异常,按继续 (F5) 让异常像在调试器之外一样冒泡。任何正常的异常都会在这些事件中结束,但这个不会。

Form1.cs

    public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
textBox1.DataBindings.Add("Text", this, "TestValue", true, DataSourceUpdateMode.OnPropertyChanged);
}

private string _TestValue = "";
public string TestValue
{
get{return _TestValue;}
set
{
_TestValue = value;
throw new Exception("Something bad happened in here");
}
}

Program.cs

static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += ThreadExceptionHandler;
AppDomain.CurrentDomain.UnhandledException += new System.UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

Application.Run(new Form1());
}

private static void ThreadExceptionHandler(object sender, System.Threading.ThreadExceptionEventArgs args)
{
try
{
//RR.Common.ErrorLogRt.WriteError(args.Exception.StackTrace.ToString(), args.Exception.Message.ToString(), true);
MessageBox.Show(args.Exception.Message);
}
catch
{
MessageBox.Show("Error writing to exception log. This program will now terminate abnormally.");
Application.Exit();
}
}

static void CurrentDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
{
try
{
if (e != null)
{
Exception ex = e.ExceptionObject as Exception;
//RR.Common.ErrorLogRt.WriteError(ex.StackTrace.ToString(), ex.Message.ToString(), true);
MessageBox.Show(ex.Message);
}
else
{
MessageBox.Show("Unhandled Error: " + e.ToString());
}
}
catch
{
MessageBox.Show("Error writing to exception log. This program will now terminate abnormally.");
Application.Exit();
}
}


static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
try
{
if (e != null && e.Exception != null && e.Exception.InnerException != null)
{
//The unobserved exception is always the same, The actual exception that cause it will be the inner exception.
Exception ex = e.Exception.InnerException;
MessageBox.Show(e.Exception.Message);
//RR.Common.ErrorLogRt.WriteError(ex.StackTrace.ToString(), ex.Message.ToString(), true);
}
else
{
MessageBox.Show("Unhandled Error: " + e.ToString());
}


}
catch
{
MessageBox.Show("Error writing to exception log. This program will now terminate abnormally.");
Application.Exit();
}
}



}

最佳答案

Remarks from Binding.FormattingEnabled Property

Setting this property to true also enables error-handling behavior and causes the BindingComplete event to be raised. The handler of this event can take the appropriate action, based on the success, error, or exceptions in the binding process, by examining the BindingCompleteState property of the BindingCompleteEventArgs parameter.

The code involved

internal bool PushData(bool force)
{
Exception ex = null;
if (!force && this.ControlUpdateMode == ControlUpdateMode.Never)
{
return false;
}
if (this.inPushOrPull && this.formattingEnabled)
{
return false;
}
this.inPushOrPull = true;
try
{
if (this.IsBinding)
{
object value = this.bindToObject.GetValue();
object propValue = this.FormatObject(value);
this.SetPropValue(propValue);
this.modified = false;
}
else
{
this.SetPropValue(null);
}
}
catch (Exception ex2)
{
ex = ex2;
if (!this.FormattingEnabled)
{
throw;
}
}
finally
{
this.inPushOrPull = false;
}
if (this.FormattingEnabled)
{
BindingCompleteEventArgs bindingCompleteEventArgs = this.CreateBindingCompleteEventArgs(BindingCompleteContext.ControlUpdate, ex);
this.OnBindingComplete(bindingCompleteEventArgs);
return bindingCompleteEventArgs.Cancel;
}
return false;
}

如您所见,将第 4 个参数传递为 true:DataBindings.Add("Text", this, "TestValue", true 负责捕获 PushData 中的异常> 并将其传递给 BindingComplete 事件。除了 BindingComplete 之外,没有其他方法(AppDomain.CurrentDomain.FirstChanceException 除外)可以找到异常> 如果启用格式。

关于c# - 绑定(bind)属性的 Set 方法中的异常未被 Application.ThreadException 事件捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24702330/

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