iT邦幫忙

0

[WinForm][C#]為什麼跨執行緒作業可以get控制項,不能set控制項

在實作時,發現這個現象,請教各位大大,這當中的原理.
謝謝~

set控制項

private System.Timers.Timer _TimersTimer;


private void Timer22_f_Load(object sender, EventArgs e)
{
    this._TimersTimer = new System.Timers.Timer();
    this._TimersTimer.Interval = 100;
    this._TimersTimer.Elapsed += new System.Timers.ElapsedEventHandler(_TimersTimer_Elapsed); 
    this._TimersTimer.Start();
} 

void _TimersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{ 
    label1.Text = (int.Parse(label1.Text) + 1).ToString(); 
}
   

出現錯誤訊息 : 跨執行緒作業無效: 存取控制項 'label1' 時所使用的執行緒與建立控制項的執行緒不同。

但如果不要存,只有取的話,卻可以.
為什麼會這樣呢?

    void _TimersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    { 
        int iTest = (int.Parse(label1.Text) + 1); 
        Console.WriteLine(iTest);
    }
看更多先前的討論...收起先前的討論...
weiclin iT邦高手 4 級 ‧ 2018-01-02 17:14:19 檢舉
想想一個可能性: 如果兩個執行緒同時 set 怎麼辦?
圓頭人 iT邦新手 2 級 ‧ 2018-01-03 08:47:46 檢舉
聽起來要有lock機制,才能避免被同時改的問題.
但如果只是訪問機制,沒有lock,也不能解決這個問題,不太明白訪問機制的存在用意是?
還是說這個訪問機制就是要配合lock使用,不能單獨使用呢?
或是有什麼情況下可以單獨使用,不需要用到lock呢?
delegate void UpdateControl(Control Ctrl, string Msg);
private object _objLock = new object();
void _mUpdateControl(Control Ctrl, string Msg)
{
if (Ctrl is Label)
((Label)Ctrl).Text = Msg;
}

# lock
delegate void UpdateControl(Control Ctrl, string Msg);
private object _objLock = new object();
void _mUpdateControl(Control Ctrl, string Msg)
{
lock (this._objLock)
{
if (Ctrl is Label)
((Label)Ctrl).Text = Msg;
}
}
weiclin iT邦高手 4 級 ‧ 2018-01-03 12:40:27 檢舉
這麼說吧, 因為允許多個 thread set 會產生很不穩定的程式, 所以近來的趨勢是語言會阻止你這麼做, 並強迫你使用 thread safe 的方法去執行, 可以參考: https://stackoverflow.com/questions/661561/how-do-i-update-the-gui-from-another-thread-in-c
圓頭人 iT邦新手 2 級 ‧ 2018-01-04 08:41:27 檢舉
原來如此...
因為這樣會產生不穩定程式,所以大家想辦法弄出又可以thread set又穩定的程式
所以就有了這些寫法,甚至語言框架直接檢查不讓我們寫出這樣危險的東西.
謝謝大大~

尚未有邦友回答

立即登入回答