2012-03-09 65 views
0

我試圖更新一個進度條,同時在一個單獨的線程上做一些數據類型檢查,似乎進度條的值和實際顯示的值之間有一個延遲。control.invoke()問題

以下代碼由非GUI線程執行並用於引發事件。

protected virtual void OnUpdateProgressBar(object sender, ProgressBarEventArgs e) 
    { 
     EventHandler<ProgressBarEventArgs> TempHandler = UpdateProgressBar; 

     //Avoid possible race condition. 
     if (TempHandler != null) 
     { 
      TempHandler(this, e); 
     } 
    } 

我已經創建了一個單獨的類用於更新進度條,當我創建它的一個實例,我通過到進度條的引用。下面是整個班級。

public class ProgressBarChanged 
{ 
    ProgressBar statusBar; 

    public ProgressBarChanged(ProgressBar pb) 
    { 
     statusBar = pb; 
     statusBar.Value = 0; 
    } 
    public ProgressBarChanged() 
    { 
    } 

    public void subscribeToEvent(DataVerification test) 
    { 
     test.UpdateProgressBar += new EventHandler<ProgressBarEventArgs>(incrementPB); 
    } 

    public void incrementPB(object sender, ProgressBarEventArgs e) 
    { 
     Action action =() => 
     { 
      if (e.CurrentRow == e.FinalRow - 10) 
      { 
       int i = 5; 
      } 
      statusBar.Maximum = e.FinalRow; 
      statusBar.Value = e.CurrentRow; 
     }; 

     if(statusBar.InvokeRequired) 
      statusBar.Invoke(action); 
     else 
      action(); 
    } 
} 

我上傳了一個屏幕快照,顯示進度條和實際值。 任何想法???

感謝

enter image description here

+0

你嘗試過'statusBar.Invoke(incrementPB,sender,e);'? – Steve 2012-03-09 16:21:02

+0

試了兩個statusBar.Invoke(incrementPB,發件人,e);和statusBar.Invoke(incrementPB(sender,e));既沒有工作。 – 2012-03-09 16:24:06

+0

@ Ken2K,感謝您整理圖片。 – 2012-03-09 16:27:13

回答

3

該progessbar是一個簡單的反饋給用戶,而不是一個精確的儀器。這是一個奶嘴。

它還包含它自己的異步邏輯來更新屏幕(獨立於消息循環)。這使得它可能會落後一點。

有什麼大不了的?

要獲得更準確的結果,請將您的範圍劃分爲< 100個細分受衆羣,並執行更少的更新。

+0

@目前事件在每行處理= 130,000次後得到提升。虐待嘗試,正如你所建議的,並提出它不到100次,看看是否能解決這個問題。感謝您的幫助 – 2012-03-09 16:31:32

+2

@HansRudel如果價值只更新100次(不是13萬次),它也會減少很多CPU的消耗,所以這是個好主意。 – ken2k 2012-03-09 16:39:31

+0

@ ken2k:正式指出,謝謝。 – 2012-03-09 16:53:29

0

延遲是相當正常的。畢竟,在UI線程中調用一個方法意味着Windows將分派一條消息,並且如果您的線程足夠快(並且CPU消耗),那麼它會比UI顯得更快。

+0

:謝謝你的回覆。根據Skeet先生的帖子http://stackoverflow.com/questions/229554/whats-the-difference-between-invoke-and-begininvoke我雖然說線程會等待GUI來處理進度條更新。還是它會改變內部價值,然後花時間來實際展示更新?如果是的話,有沒有辦法解決這個延遲? – 2012-03-09 16:26:45

+0

線程將等待PB接受新的值_。視覺更新單獨發生。 – 2012-03-09 16:29:24

+0

嘗試在每次更改值後調用Refresh(但以這種方式刷新progbar並不是最佳選擇)。 – ebutusov 2012-03-09 16:35:23