gpt4 book ai didi

c# - 在多线程应用程序中使用 MessageBox 显示异常信息

转载 作者:太空宇宙 更新时间:2023-11-03 21:55:50 25 4
gpt4 key购买 nike

您好,我正在使用 winform 并尝试使用 MessageBox 进行异常处理。奇怪的是,MessageBox 仅在主窗体(下面代码中的“Form1”)关闭后出现。

public class Worker {
/* edited (see below)
public void doWork() {
try {
// do something
client.Connect(serverAddress);
stream = client.GetStream();
}
catch(Exception e) {
MessageBox.Show(e.ToString(),
"This will not show up until Form1 is closed");
}
}
*/
}

public class Form1 {
/* edited (see below)
* public void threadProc() {
* Worker worker = new Worker();
* worker.doWork();
* }
*/
void button_Click(object sender, EventArgs e) {
// create a thread that will end up throwing an exception
Thread thread = new Thread(threadProc);
thread.Start();
}
}

使用 MessageBox 进行异常处理的更好方法是什么?


...所以我在 UI 线程中添加了一些用于 MessageBox-ing 的代码,但问题仍然存在。

public class WorkExceptionArgs : EventArgs {
public Exception e;
public WorkExceptionArgs (Exception e) { this.e = e; }
}
public partial class Worker1 { // renamed (Worker->Worker1)
/* (edited) Now Worker1 doesn't trigger any event (see below)
public event EventHandler<WorkExceptionArgs> workException;
*/
public void doWork() {
try {
// do something
client.Connect(serverAddress);
stream = client.GetStream();
}
catch(Exception e) {
/* (edited) suppose Worker1 never throws any exception (see below)
* // trigger event that will cause MessageBox-ing by UI thread
* workException(this, new WorkExceptionArgs(e));
*/
}
}
}
public partial class Form1 {
public void threadProc() {
Worker1 worker1 = new Worker();
/* (edited) Now Worker1 never throws any exception
* worker.workException += new EventHandler<WorkException>(worker_WorkException);
*/
worker1.doWork();
// (added) After doWork() is done, Form1 creates Worker2
Worker2 w2 = new Worker2(this, this.form2);
w2.workException += new EventHandlerArgs<WorkExceptionArgs>(form2.worker2_WorkException);
w2.doSomeOtherWork();
}
/* public void worker_WorkException(object sender, WorkExceptionArgs eArg) {
* MessageBox.Show(eArg.e.ToString(), "Still not showing");
* } */
Form2 form2 = new Form2(); // (added) At first form2 is hidden (see below)
}

实际上已经有另一种形式和另一种 worker 。一旦 Worker(Worker1) 连接到服务器,Form1 隐藏 (.Hide()),Form2 显示 (.Show()),Worker2 开始使用 Worker1 建立的连接。

public class Worker2 {
Worker2(Worker1 w1, Form2 frm2) { this.w1=w1; this.frm2=frm2; }
public Worker1 w1;
public Form2 frm2;
public event EventHandler<WorkExceptionArgs> workException;
public void doSomeOtherWork() { // do some other, using data in Worker 1.
try { // This will throw an exception
BinaryFormatter formatter = new BinaryFormatter();
MyObj mo = (MyObj)formatter.Deserialize(w1.getStream());
}
catch(Exception e) {
workException(this, new WorkExceptionArgs(e));
}
}
}

public class Form2 {
public Form2(Form1 frm1) { // to switch from frm1 to frm2
InitializeComponent();
this.frm1 = frm1;
}
public Frm1 frm1 {get;set;}
public void worker2_WorkException(object sender, WorkExceptionArgs ea) {
MessageBox.Show(this, ea.e.ToString(), "SHOWS ONLY IF FORM2 IS CLOSED");
}

}

public partial class Form1 {
delegate void switchWindow_Callback();
public void switchWindow() { this.Hide(); form2.Show(); }
public void switchWindowCb(object sender, EventArgs e) {
if(this.InvokeRequired) {
SwitchWindow_Callback hcb = new SwitchWindow_Callback(switchWindow);
this.Invoke(hcb, new object[] {});
}
else { this.switchWindow(); }
}
}

最佳答案

实际上,我敢打赌 MessageBox 出现在主窗体后面,只有在关闭它之前您才会看到它。

最好让 UI 线程(创建并拥有 Form1 的线程)执行 MessageBox-ing。您要么想要创建事件,要么在您的工作类中有一个错误回调委托(delegate)。

但是,BackgroundWorker 可能值得在这里检查,而不是尝试自己动手。假设这是一个致命异常,您可以保存和检索错误状态,并在线程结束时自动调用一个事件。

关于c# - 在多线程应用程序中使用 MessageBox 显示异常信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12347531/

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