2010-11-05 38 views
0

我在這行代碼得到一個InvalidOperationException運行時錯誤儘管使用調用

SynchronizedInvoke(this,() => this.Opacity = this.Opacity + 0.05); 

要具體介紹一下運行時錯誤...

跨線程操作無效:控制'frmToaster'從其創建線程以外的線程訪問。

我用SynchronizedInvoke方法,建議在Stack Overflow上的其他地方,以確保需要而定的調用使用。

static void SynchronizedInvoke(ISynchronizeInvoke sync, Action action) 
{ 
    // If the invoke is not required, then invoke here and get out. 
    if (!sync.InvokeRequired) 
    { 
     // Execute action. 
     action(); 

     // Get out. 
     return; 
    } 

    // Marshal to the required thread. 
    sync.Invoke(action, new object[] { }); 
} 

這段代碼如何生成,即使我用SynchronizeInvoke避免它有關跨線運行時錯誤調用?

回答

2

當sync.InvokeRequired爲false時,您會得到這個結果。這不好,應該是真的。在action()上設置一個斷點。並找出當你休息時發生了什麼。

這是您在窗體顯示時使用的那種代碼,當表單的Handle尚未創建時,InvokeRequired爲false。確保此代碼不會運行得太快,您必須等到表單的OnHandleCreated()方法運行或Load事件觸發爲止,無論哪一個更容易覆蓋。

另一個簡單的解決方法是僅僅不測試InvokeRequired,你知道它應該總是正確的,因爲你正在一個工作線程上運行它。使用BeginInvoke而不是Invoke,直到UI線程重新進入消息循環後,lambda纔會運行,之後創建表單。最終的解決方案,燒燬一個線程只是爲了淡化表單,使用winforms Timer。爲您節省了一個兆字節。

-1

我不認爲lambda表達式是線程安全的