none
C# 關於執行緒執使用的一些問題 RRS feed

  • 問題

  • Hello 各位前輩好

    想跟各位請教一下關於執行緒在使用的一些問題

    像是在使用上要避免那些用法,或是那些用法程式邏輯沒錯

    但是執行起來可能會導致系統爆炸(而且還不會噴exception...)

    不知道前輩們有沒有遇過什麼類似的使用情況可以分享一下

    另外我有幾種寫法也想跟大家討論

    1.開一個執行緒跟硬體要資料

    //大概語法類似這樣
    //建立一個Class
    public Class DEVICEREAD{
    
        public delegate void DataDelegate(int Code, string Message);
        public event  DataDelegate DataChange;
    
        Thread thr_read;
        thr_read  = new Thread(ReadDevice);
        thr_read.Start();
    
        privete void ReadDevice(){
            While(true){
            //假設是走COM或是網路讀取資料之後
            //觸發Event事件,使用Class時監聽事件看值的變化
            DataChange(1,"1");
            
            Thread.Sleep(1000);
            }
        }
    
    }
    
    //使用Class接收設備值
    DEVICEREAD deviceread = new DEVICEREAD();
    deviceread.DataChange += GetData();
    
    void GetData(Code,Message){
        //處理觸發訊號
    }

    像這樣開執行緒一直跟設備要資料應該滿多人會這樣

    我想知道一下,因為我開執行緒去觸發 Event

    那我再使用Class的時候,建立了 

    void GetData(Code,Message){}

    這個接收Event的部分,是會在主UI執行緒下監聽嗎

    還是會再另外一個執行緒執行裏頭執行

    那如果我在裡面又去呼叫另一個Method

    void GetData(Code,Message){
    UpdateData(Message);
    }

    那這兩個是在同一個執行緒底的嗎

    像我如果再下面兩個作揖些Form UI設定 (TextBox1.text = Message 之類的)

    也會出現跨執行緒的存取問題嗎

    UpdateData(Message);  或是  GetData(Code,Message)


    大概就是這些問題,不知道前輩可以分享一下使用上遇過的一些窘境

    2016年12月23日 下午 03:48

解答

  • 為了便於討論, 假設你開出來的 Thread 稱之為 AThread  , 原來 Form 所在的 Thread 稱之為 UIThread.

    你從 AThread 去觸發一個 Event, 在沒有特別的同步處理或開新的Thread 狀況下, 所有掛進這個  Event 的 事件委派函式都會在 AThread 中執行.

    不論這些涵式如何的層層呼叫, 只要沒有轉移到其他的 Thread  (如: 開新的 Thread 或是 Invoke 到 UIThread 等等  之類的), 它永遠都會在 AThread 中執行.

    因此, 在這個狀況下, 從 AThread 只要是會動到 UIThread 上的控制項, 都必須使用 Control.Invoke ( 或 Control.BeginInvoke), 讓函式會執行在與 Control 相同的 Thread 上 (以這個例子就是 UIThread)


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。




    2016年12月23日 下午 07:05
    版主

所有回覆

  • 為了便於討論, 假設你開出來的 Thread 稱之為 AThread  , 原來 Form 所在的 Thread 稱之為 UIThread.

    你從 AThread 去觸發一個 Event, 在沒有特別的同步處理或開新的Thread 狀況下, 所有掛進這個  Event 的 事件委派函式都會在 AThread 中執行.

    不論這些涵式如何的層層呼叫, 只要沒有轉移到其他的 Thread  (如: 開新的 Thread 或是 Invoke 到 UIThread 等等  之類的), 它永遠都會在 AThread 中執行.

    因此, 在這個狀況下, 從 AThread 只要是會動到 UIThread 上的控制項, 都必須使用 Control.Invoke ( 或 Control.BeginInvoke), 讓函式會執行在與 Control 相同的 Thread 上 (以這個例子就是 UIThread)


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。




    2016年12月23日 下午 07:05
    版主
  • 如果你是 SerialPort 接收多緒寫的有問題,暴衝到 5xx 條執行緒,然後程式鎖死,這邊 blog 有在談這件事。

    [.Net] 資料接收的常識

    你的 GetData / UpdateData 對象很重要,如果是記憶體,基本上不會出事,如果是資料庫,有可能鎖死,上面那個是裝置鎖死的案例。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2016年12月24日 上午 09:11
  • 感謝兩位的回覆

    還有提供的Blog!!!!!

    剛好最近遇到執行緒使用的問題

    另外請問一下這樣的寫法,是執行完裡面的程式,執行緒就會自己關閉嗎

    new Thread(()=>{
        /*TODO*/
    }).Start();

    像我會用的方式是開 Athread 一直跟硬體要資料

    那取得資料之後用上面程式碼這種方式去處理要到的資料
    因為有時處理邏輯比較複雜的話,怕在同一個執行緒底下
    邏輯沒處理完或卡住了,那跟設備要資料也就停掉了

    總結

    1. 開Athread跟硬體下cmd要資料後,如果直接處理取的資料後的邏輯
        處理時間太久,或是邏輯錯誤卡死,是不是會導致 Athread 停住,導致沒辦法下 cmd繼續要資料

    2.這種使用方法,裡面程序跑完執行緒會關閉嗎

    new Thread(()=>{ /*TODO*/ }).Start();





    • 已編輯 open852134 2016年12月25日 上午 07:20
    2016年12月25日 上午 07:19
  • 是的, 只要執行緒內部的程序執行完畢, 就會關閉。

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2016年12月25日 上午 09:37
    版主