最近敲代码发现一个问题,C#当中自带的MessageBox.show()弹框,默认是模态对话框,是阻塞线程的,也就是说你不点击弹框上的按钮,它就会一直显示在那里,MessageBox.show()后面的代码是停止的不往后执行,但是主程序仍然会响应其他消息,比如Timer事件,造成时序逻辑混乱,会一直弹窗出来。直到你按弹框上的按钮才会停止执行。
如下显示:
if (true)
{
MessageBox.Show(
Messagesinfo.msg_err1
Messagesinfo.error,
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
return false;
}
修改方法:
if (true)
{
this.BeginInvoke((MethodInvoker)delegate {
MessageBox.Show(
Messagesinfo.msg_err_sv_INPNnotset,
Messagesinfo.msg_title_error,
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
return false;
}
BeginInvoke()
方法是.NET Framework中的Control
类的一个方法。它用于在控件的拥有线程上异步执行指定的委托,无论这个方法是从哪个线程调用的。
在Windows窗体中,UI元素(例如按钮、文本框等)只能在创建它们的线程(通常被称为UI线程)上访问。如果你尝试从另一个线程访问UI元素,可能会导致异常或不可预见的行为。BeginInvoke()
方法提供了一种在UI线程上执行代码的方式,即使这个代码是从另一个线程调用的。
BeginInvoke()
方法的使用方法是,你传递一个委托(和任何需要的参数)给它,然后它将这个委托排入UI线程的事件队列。当UI线程下次运行消息循环时,它会执行这个委托。
BeginInvoke()
方法会立即返回,并且不会等待委托的执行。它返回一个IAsyncResult
对象,你可以使用这个对象来查询操作的状态或等待操作完成。
使用BeginInvoke()
,比如更新文本框的操作会在UI线程上执行,所以这是安全的。同时,由于BeginInvoke()
方法立即返回,所以这段代码不会阻塞后台线程。