2013-07-07 65 views
-4

我已經得到了這個錯誤:線程錯誤

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll

Additional information: Cross-thread operation not valid: Control 'Redlight' accessed from a thread other than the thread it was created on.

紅燈和綠光是pictureBoxes。 基本上,我希望它能夠做的就是每秒鐘在每幅圖片之間交替。 我在這個網站搜索了類似的錯誤,我看到它與「調用」有關,但我甚至不知道那是什麼,有人能夠啓發我嗎?

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.Threading; 

namespace EMCTool 
{ 
    public partial class EMCTool_MainForm : Form 
    { 
     bool offOn = false; 

     public EMCTool_MainForm() 
     { 
      InitializeComponent(); 
     } 

     private void EMCTool_MainForm_Load(object sender, EventArgs e) 
     { 
      System.Threading.Timer timer = new System.Threading.Timer(new System.Threading.TimerCallback(timerCallback), null, 0, 1000); 
     } 

     private void timerCallback(object obj) 
     { 
      if (offOn == false) 
      { 
       Redlight.Show(); 
       offOn = true; 
      } 
      else 
      { 
       Greenlight.Show(); 
       offOn = false; 
      } 
     } 
    } 
} 

回答

4

當您嘗試從任何未創建的線程更新UI元素時,會出現「跨線程」錯誤。

Windows窗體中的控件綁定到特定的線程並且不是線程安全的。因此,如果您從其他線程調用控件的方法,則必須使用控件的一個invoke方法將調用編組到適當的線程。這個屬性可以用來確定你是否必須調用一個invoke方法,如果你不知道哪個線程擁有一個控件,這個方法會很有用。

參考here更多

試試這個。這工作正常,我

if (pictureBoxname.InvokeRequired) 
        pictureBoxname.Invoke(new MethodInvoker(delegate 
        { 
      //access picturebox here 
        })); 
       else 
     { 

    //access picturebox here 
} 
+0

哦好吧,這如何調用事工作,這是什麼我做什麼? 編輯:我測試過,它的工作。 – Evan

+1

Invoke方法委託在其上創建的線程(即UI線程)上完成與UI相關的處理。 –

+1

@ user1880591它將您的調用發送到創建控件的線程,並且該工作可以完成。 – Shaharyar

0

另一種解決方案是使用System.Timers.Timer擁有財產對於SynchronizingObject所以設置這個,它會工作:

timer.SynchronizingObject = This 

或者使用System.Windows.Forms.Timer因爲它不會引發異常(它提出了在UI線程Tick事件)。

1

在WinForms的項目更好地運用System.Windows.Forms.Timer,因爲它的UI線程上自動調用Tick事件:

private System.Windows.Forms.Timer _timer; 

private void EMCTool_MainForm_Load(object sender, EventArgs e) 
{ 
    _timer = new System.Windows.Forms.Timer { Interval = 1000 }; 
    _timer.Tick += Timer_Tick; 
    _timer.Start(); 
} 

private void Timer_Tick(object sender, EventArgs e) 
{ 
    if (offOn) { 
     Greenlight.Show(); 
    } else { 
     Redlight.Show(); 
    } 
    offOn = !offOn; 
}