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    };   }   }

同時,需要注意的是如果線程中打開某個窗體,並且要為打開的窗體附加樣式,一定要確保加載樣式的邏輯和打開窗體的邏輯在同一個線程里!!!!!

此文僅做個人積累。。。。。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM