Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更新关闭窗体线程中的Toolstripstatuslabel_C#_Multithreading_Winforms_Mdiparent_Toolstripstatuslabel - Fatal编程技术网

C# 更新关闭窗体线程中的Toolstripstatuslabel

C# 更新关闭窗体线程中的Toolstripstatuslabel,c#,multithreading,winforms,mdiparent,toolstripstatuslabel,C#,Multithreading,Winforms,Mdiparent,Toolstripstatuslabel,我有一张订单。订单完成后,我使用一个线程将订单通过电子邮件发送给供应商。该线程用于在订单导出为pdf并发送时防止系统挂起 问题是:一旦威胁无误完成,我想在MDIParent Toolstripstatuslabel上放置一条消息,以确认订单已发送。但我得到一个错误:“System.NullReferenceException:对象引用未设置为对象的实例”。我可能错了,它指的是子窗口在父窗体关闭时释放了toolstripstatuslabel引用,因此威胁无法再访问它。我知道最简单的解决方法是使用

我有一张订单。订单完成后,我使用一个线程将订单通过电子邮件发送给供应商。该线程用于在订单导出为pdf并发送时防止系统挂起

问题是:一旦威胁无误完成,我想在MDIParent Toolstripstatuslabel上放置一条消息,以确认订单已发送。但我得到一个错误:“System.NullReferenceException:对象引用未设置为对象的实例”。我可能错了,它指的是子窗口在父窗体关闭时释放了toolstripstatuslabel引用,因此威胁无法再访问它。我知道最简单的解决方法是使用MessageBox来确认一切都进行得很好……但是如果你能做到优雅,为什么要让它变得简单呢

所以我的问题是:如何从威胁中引用父窗体中的控件?我试着查看invoke,但不确定如何实现它,或者它是否真的是正确的方向

编辑:

我的代码来自子窗体

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。