2013-07-11 50 views
1

我正在開發的應用程序是現有應用程序的插件,並且第一次運行插件時一切正常。但是,當我第二次打開插件時,出現以下錯誤:「調用或BeginInvoke無法在控件上調用,直到窗口句柄被創建」僅在第二次表單打開時發生

InvalidOperationException未處理 - 在創建窗口句柄之前,無法在控件上調用Invoke或BeginInvoke。

我理解競爭條件,並從一切我讀過,試圖HandleCreated之前訪問表單元素時出現此錯誤是真的,但我想不出爲什麼發生這種情況僅僅是第二次我打開插件。

這裏是插件代碼。調用SetProgressBar()時出現錯誤:

private MainForm mainForm; 

    public void StartPlugin() 
    { 
     mainForm = new MainForm (this); 
     mainForm .ShowDialog(); 
    } 

    public bool GetJoinEnabled() 
    { 
     mainForm.SetProgressBar(3); 
    } 

這是我的主要形式有:

private Thread m_JoinThread; 
    private JoinPlugin m_Join; 

    public MainForm(JoinPlugin zig) 
    { 
     m_Join = zig; 
     InitializeComponent(); 
     m_JoinThread= new Thread(new ThreadStart(GetJoinData)); 
     m_JoinThread.Start(); 
    } 

    private void GetJoinData() 
    { 
     //Get enable join data 
     bool result = m_Join.GetJoinEnabled(); 
    } 

    public void SetProgressBar(int value) 
    { 
     SetProgressCallback del = new SetProgressCallback(SetProgressBarControl); 
     this.Invoke(del, value); 
    } 

    private void SetProgressBarControl(int value) 
    { 
     progressBar.Value = value; 
    } 
+1

如果在'mainForm.ShowDialog();'之後添加'mainForm.Dispose();'會發生嗎? – keyboardP

+0

很奇怪你的'MainForm'變成定義代碼中的'ZigbeeJoinForm'了嗎?除非你的'MainForm'繼承'ZigbeeJoinForm'。 –

+0

'delegate'是一個關鍵字,它不能用於變量名,但你的代碼行是一個例外? 'SetProgressCallback delegate = new SetProgressCallback(SetProgressBarControl);' –

回答

3

我猜了一點,但我前段時間碰到了同樣的問題。

你開始在形式構造一個線程:

m_JoinThread.Start(); 

這immediatedly開始線程,並調用Invoke地方。此時,表格並未完全啓動。
移動代碼到Load事件:

public ZigbeeJoinForm_Load() 
{ 
    m_JoinThread= new Thread(new ThreadStart(GetJoinData)); 
    m_JoinThread.Start(); 
} 

這確保了形式完成初始化,並呼籲Invoke是安全的呢。

相關問題