C# 更新关闭窗体线程中的Toolstripstatuslabel
我有一张订单。订单完成后,我使用一个线程将订单通过电子邮件发送给供应商。该线程用于在订单导出为pdf并发送时防止系统挂起 问题是:一旦威胁无误完成,我想在MDIParent Toolstripstatuslabel上放置一条消息,以确认订单已发送。但我得到一个错误:“System.NullReferenceException:对象引用未设置为对象的实例”。我可能错了,它指的是子窗口在父窗体关闭时释放了toolstripstatuslabel引用,因此威胁无法再访问它。我知道最简单的解决方法是使用MessageBox来确认一切都进行得很好……但是如果你能做到优雅,为什么要让它变得简单呢 所以我的问题是:如何从威胁中引用父窗体中的控件?我试着查看invoke,但不确定如何实现它,或者它是否真的是正确的方向 编辑: 我的代码来自子窗体C# 更新关闭窗体线程中的Toolstripstatuslabel,c#,multithreading,winforms,mdiparent,toolstripstatuslabel,C#,Multithreading,Winforms,Mdiparent,Toolstripstatuslabel,我有一张订单。订单完成后,我使用一个线程将订单通过电子邮件发送给供应商。该线程用于在订单导出为pdf并发送时防止系统挂起 问题是:一旦威胁无误完成,我想在MDIParent Toolstripstatuslabel上放置一条消息,以确认订单已发送。但我得到一个错误:“System.NullReferenceException:对象引用未设置为对象的实例”。我可能错了,它指的是子窗口在父窗体关闭时释放了toolstripstatuslabel引用,因此威胁无法再访问它。我知道最简单的解决方法是使用
public partial class frm_n_order : Form
{
.
.
private void bProcess_Click(object sender, EventArgs e)
{
.
.
.
new Thread(new ThreadStart(delegate
{
fExportOrder(strOrderNo);
fSendMailv2(strPlant, strSupCode, strOrderNo);
})).Start();
this.close();
}
private void fExportOrder(string strOrderNo)
{
//export order to pdf
}
private void fSendMailv2(string strPlant, string strSupCode, string strOrderNo);
{
// get pdf
// get email address
try
{
// send email
((MDIParent1)MdiParent).tsslMain.Text = "Order No:" + strOrderNo + " was successfully send to " + strEmails; //here I need to find a different way of accessing the Toolstripstatuslabel in the parent form
}
catch
{
MessageBox.Show("Email did not send");
}
}
}
编辑:
好吧,在花了一天多的时间试图弄清楚如何使用Invoke之后,我意识到,虽然使用线程似乎是一种很好的做法,但这不是我的答案。我的问题与子窗体关闭处理所有控件直接相关,这样它就失去了对父控件的引用。为了解决这个问题,我做了以下工作: 在我的儿童课上,我补充道:
public static Form IsFormAlreadyOpen(Type FormType)
{
foreach (Form OpenForm in Application.OpenForms)
{
if (OpenForm.GetType() == FormType)
return OpenForm;
}
return null;
}
public static Form IsFormAlreadyOpen(Type FormType)
{
foreach (Form OpenForm in Application.OpenForms)
{
if (OpenForm.GetType() == FormType)
return OpenForm;
}
return null;
}
我不认为这是最优雅的解决方案,但理论是当我需要访问Toolstripstatuslabel时,我的父窗体将始终处于打开状态。因此,我基本上遍历了所有打开的表单,以找到对活动MdiParent实例的引用,然后将该引用传递回调用方。在线程中,我使用以下代码
MDIParent1 fm = null;
if ((fm = (MDIParent1)IsFormAlreadyOpen(typeof(MDIParent1))) != null)
{
fm.Toolstripstatuslabel1.Text = "Order No:" + strOrderNo + " was successfully send to " + strEmails;
}
MDIParent1 fm = null;
if ((fm = (MDIParent1)IsFormAlreadyOpen(typeof(MDIParent1))) != null)
{
fm.Toolstripstatuslabel1.Text = "Order No:" + strOrderNo + " was successfully send to " + strEmails;
}
我仍然在寻找一种更好的方法,但目前这是可行的。好吧,在花了一天多的时间试图弄清楚如何使用Invoke之后,我意识到,虽然使用线程似乎是一种很好的做法,但这不是我的答案。我的问题与子窗体关闭处理所有控件直接相关,这样它就失去了对父控件的引用。为了解决这个问题,我做了以下工作: 在我的儿童课上,我补充道:
public static Form IsFormAlreadyOpen(Type FormType)
{
foreach (Form OpenForm in Application.OpenForms)
{
if (OpenForm.GetType() == FormType)
return OpenForm;
}
return null;
}
public static Form IsFormAlreadyOpen(Type FormType)
{
foreach (Form OpenForm in Application.OpenForms)
{
if (OpenForm.GetType() == FormType)
return OpenForm;
}
return null;
}
我不认为这是最优雅的解决方案,但理论是当我需要访问Toolstripstatuslabel时,我的父窗体将始终处于打开状态。因此,我基本上遍历了所有打开的表单,以找到对活动MdiParent实例的引用,然后将该引用传递回调用方。在线程中,我使用以下代码
MDIParent1 fm = null;
if ((fm = (MDIParent1)IsFormAlreadyOpen(typeof(MDIParent1))) != null)
{
fm.Toolstripstatuslabel1.Text = "Order No:" + strOrderNo + " was successfully send to " + strEmails;
}
MDIParent1 fm = null;
if ((fm = (MDIParent1)IsFormAlreadyOpen(typeof(MDIParent1))) != null)
{
fm.Toolstripstatuslabel1.Text = "Order No:" + strOrderNo + " was successfully send to " + strEmails;
}
我仍在寻找一种更好的方法,但目前这是可行的。如果它正在关闭,并且在您尝试使用它时实际上已经消失,用户将如何看到更新?@我认为他是想更改刚刚关闭的父窗口上的toolstrip状态标签。我们能看到一些实际的代码吗?很难找出到底出了什么问题。@user1339124我试图从您的描述中找到一个解决方案,就是您应该将对父窗口的引用传递给线程,然后使用
App.Current.Dispatcher.Invoke(()=>{/*使用传递给线程的引用更新此处的状态标签*/)代码>此问题是否为您提供了解决方案@提摩太:没错,你知道我想做什么。但老实说,我觉得和调度员在一起有点不对劲。我一直在忙着阅读它,想知道如何使用它。首先,这听起来像是在使用Winforms,我更愿意看看BeginInvoke。