【SerialPort】線程間操作無效: 從不是創建控件“txtreceive”的線程訪問它。

轉載:hi.baidu.com/wxy379643276/item/d86aed8f6f87e0c4b07154e7

自己在寫串口通信的時候遇到個這樣的問題

自己是用vs2010  c#寫的錯誤提示是這樣的“線程間操作無效: 從不是創建控件“txtreceive”的線程訪問它。”  用的控件是自帶的serialPort

 txtreceive是接收區的框

開始的程序是這樣寫的  表示串口接收到數據後就能觸發事件

private void mycomm_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)

        {            

            string str = mycomm.ReadExisting().ToString();

            txtreceive.Text = txtreceive.Text + str;

        }

 運行後 用arm給串口發了個數據 提示這個錯誤  線程間操作無效: 從不是創建控件“txtreceive”的線程訪問它。

鬱悶 我就沒有用線程  怎麼會提示這個錯誤呢~~ 後來在網上查了一下  原來是存在跨線程調用控件的問題

解決方法有兩種:第一是加一句話,第二是用委託。因爲一句話成功了 我就沒有用委託了~  

1.解決方法就加了一句話

private void mycomm_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)

        {

            ////////////////////線程開始的時候加這麼一句

            Control.CheckForIllegalCrossThreadCalls = false;

        

            string str = mycomm.ReadExisting().ToString();

            txtreceive.Text = txtreceive.Text + str;

        }

ok 程序就運行成功了~


第二:
用委託,在05裏,每個控件都有個InvokeRequired的屬性~
判斷一下是不是true,是的話進行Invoke操作的,完事了~

 

//建立個委託
        private delegate void ShowDelegate(string strshow);


        public void Show(string strshow)

        {


            if (this.txtreceive.InvokeRequired)

            {

             //   this.txtreceive.BeginInvoke(new ShowDelegate(Show), strshow);//這個也可以

                this.txtreceive.Invoke(new ShowDelegate(Show), strshow);

            }

            else

            {

                    this.txtreceive.Text += strshow;


            }

        }

第一種方法只是簡單的將錯誤提示禁用了,仍然存在跨線程調用控件的問題。爲此可能造成兩個線程同時或者循環改變該控件的狀態導致線程死鎖。 

Invoke方法是同步的方法,所以執行過程是有先後順序的,所以就不會出現那個異常了 最好是用第二種方法


發佈了19 篇原創文章 · 獲贊 13 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章