2011-02-25 130 views
7

我在顯示一個動畫,而我的控件正在加載數據。當線程結束時,我隱藏動畫並顯示控件。有時Control.Invoke()掛起應用程序

protected void InvokeEnableBackControl() 
{ 
    if (this.InvokeRequired) 
    {     
     this.Invoke(new OpHandler(EnableBackControl)); 
    } 
    else 
    { 
     EnableBackControl(); 
    } 
} 

,當我執行這個代碼,主線程被下面的代碼忌用:所以我從一個線程執行這段代碼

protected virtual void EnableBackControl() 
{ 
    if (overlayAnimation.TargetControl != null) 
    { 
     overlayAnimation.TargetControl.BringToFront(); 
    } 

    overlayAnimation.SendToBack(); 
    overlayAnimation.Enabled = false; 
    overlayAnimation.Visible = false;      

}

我米不知道是否被吊死設置EnableVisible屬性。你知道任何情況下,可能會從Control.Invoke調用這些屬性的應用程序嗎?

+0

有沒有一個可識別的模式時,它掛起次? – 2011-02-25 15:50:08

+0

@不,只有「有時」。煩人。 – 2011-02-25 16:15:29

+0

記錄它掛起的* exact *語句,發佈堆棧跟蹤。 – 2011-02-25 18:01:44

回答

3

在調試中運行,使應用程序掛起,然後在Visual Studio中暫停調試並檢查線程。

+0

這是什麼答案?我使用調試器附加了進程,我暫停並檢查了線程。這就是我知道線程在第一個代碼塊中,而主線程在第二個代碼塊中的原因。 – 2011-02-25 16:17:08

+0

@DanielPeñalba這是一種幫助我的解決方案。因爲當你這樣做時,你可以看到線程掛起的確切線條。 – Andrey 2011-02-25 16:24:43

+0

我做到了。當我中斷所有線程時突出顯示的行是'overlayAnimation.Visible = false;'但通常Visual Studio(幾乎是2003)停在前一行。有時候,這就是我不確定這條線或上一條線的原因。 – 2011-02-25 16:44:30

7

我,當我執行.Invoke在後臺線程,而我的主線程仍然忙於之前碰到的問題 - 這給人的印象是應用程序掛起,因爲調用只是坐在那裏,等待主線程迴應它的注意。可能的原因:

  • 你的主線程被阻塞,在等待着什麼
  • 你的主要形式,目前有一個模式對話框了,所以它不是聽新的要求
  • 你的主線程在旋轉,要麼不斷地檢查,如果有些事情已經完成或正在做新的工作在我的情況下,主線程花了第一分鐘在緊密循環中旋轉後臺線程,所以它沒有監聽來自後臺線程的任何調用請求。

當你連接調試器時,要特別注意你的主控制MessagePump線程正在做什麼 - 我懷疑它的缺乏是你麻煩的原因。如果您發現主線程中的迴路沒有響應,請嘗試在迴路中插入一個.DoEvents,這將暫停執行並強制主線程清空消息泵並路由所有未完成的請求。

+0

謝謝,這是我的情況,並Application.DoEvents()做了伎倆。 – Tate 2012-03-20 10:23:43

0

我發現的是,控件的實際繪製/繪製可能會非常緩慢,尤其是如果您有大量的控件和/或使用雙緩衝來平滑刷新。我正在使用BeginInvoke從我從套接字接收到的數據更新列表視圖控件。有時更新發生得如此之快以至於它凍結了應用程序。我通過將異步收到的所有套接字寫入隊列,然後在單獨的線程中使數據出隊,並使用列表視圖上的開始更新結束更新來解決此問題,並完成所有未完成的更新。這削減了大量額外的重繪工作,使應用程序響應更多。

0

你必須使用BeginInvoke inested Invoke看到這個Link