C#关于多线程之线程中窗体之间的控件值调用

本周做了一个线程中打开多个窗体的东西,父窗体打开子窗体,父窗体获取子窗体的控件值,此处我在打开窗体时,分别在不同的线程中打开的,不做多考虑,上手就做,到后来程序崩掉了,原因是什么了,找不到对应的控件,这是为什么了,因为创建子窗体的过程和创建父窗体的过程并不在同一线程中,程序无法获知你要找的控件,那么对于这种情况,就得用到vs自带的Control.InvokeRequired方法,此方法返回的结果为bool类型,主要是“ 获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。”   

关于Invoke()方法,传递参数为一个方法委托,它采用的参数的数量和类型与 args 参数中所包含的相同。摘要: 在拥有控件的基础窗口句柄的线程上,用指定的参数列表执行指定委托。

详例说明

           //第一步:打开窗体
            SendEmailProgress  progress = new SendEmailProgress();
            progress.Closing += (s, ev) =>
                {
                    if (progress.IsEnabledCloseForm)
                    {
                        progress.IsAlreadyClosed = true;
                        TaxCardFactory.ReleaseCard();
                    }
                    else
                    {
                        ev.Cancel = true;
                        CommonClass.Message("323", "", null);
                    }

                };
            
             Control.CheckForIllegalCrossThreadCalls = false; //在这个类中我们不检查跨线程的调用是否合法
             thread = new Thread(new ParameterizedThreadStart(ShowCommonProgressFormDialog));
             thread.Start();
             SendEmailProgress.TaxCardInfo info = progress.GetCardInfo("AutoExtract", taxCardModel);

SendEmailProgress.cs文件 错误的代码:        
public TaxCardInfo GetCardInfo(string type, ITaxCard card)    {     using (EditTaxCardPwd editTaxCardForm=new EditTaxCardPwd(type,card)) {    if (editTaxCardForm.ShowDialog(this) != DialogResult.OK)    {    return null;    }    return new TaxCardInfo()    { CardPwd = editTaxCardForm.goldenPlatePwd    };    }    } 正确的代码:       public TaxCardInfo GetCardInfo(string type, ITaxCard card) {   if (InvokeRequired) {   return this.Invoke(new Func<string, ITaxCard,TaxCardInfo>(GetCardInfo),type,card) as TaxCardInfo;
//这种写法等同于定义一个委托方法,比如:   
//private delegate void GetCardInfoHandler(string type, ITaxCard card);
//GetCardInfoHandler InfoHandler=GetCardInfo; return this.Invoke(GetCardInfoHandler,new object[]{type,card});   }   
using (EditTaxCardPwd editTaxCardForm=new EditTaxCardPwd(type,card))    {   if (editTaxCardForm.ShowDialog(this) != DialogResult.OK)    {    return null;    }    return new TaxCardInfo()    {    CardPwd = editTaxCardForm.goldenPlatePwd    };   }   }

同时,需要注意的是如果线程中打开某个窗体,并且要为打开的窗体附加样式,一定要确保加载样式的逻辑和打开窗体的逻辑在同一个线程里!!!!!

此文仅做个人积累。。。。。。。

原文地址:https://www.cnblogs.com/DreakSeeker/p/8509803.html