2015-10-26 26 views
0

我有一個處理大量數據的vb.net應用程序。由於進程的內存要求我這樣做分批,總體規劃結構爲:在等待任務完成時更新UI

Do while Start < TotalNumberOfObjects 

    [cache data used for the upcoming batch] 

    For i = Start to Stop 

     [process data using multiple tasks...for example:] 
     t=taskfactory.startnew(doStuff(i)) 
     TaskList.TryAdd(t.ContinueWith(Sub()          
             Me.BeginInvoke(DelegateUpdateProgress, {progress}) 
             End Sub)) 
    Next 

    [Wait for tasks to complete... 
    Normally I would wait for the tasks using task.waitall(), 
    but this will cause the UI to wait to update until all tasks are complete] 

    Start = Stop+1 
    Stop = Stop+Increment 

    [clear data from batch that was just completed] 

loop 

什麼是正確的方法:

  1. 等待所有任務完成在轉移到下一批之前?
  2. 隨着每個任務完成,用整體進度更新UI?

我的目標框架是.NET 4.0。

我很欣賞任何輸入。

編輯:目前我使用task.continuewith()每個任務完成後更新UI,並呼籲me.beginInvoke更新形式,

TaskList.TryAdd(t.ContinueWith(Sub()          
           Me.BeginInvoke(DelegateUpdateProgress, {progress}) 
           End Sub)) 

但是,這是我怎麼會想到等待列表不兼容任務完成,task.waitall(tasklist),因爲調用task.waitall將導致UI線程等待更新,直到所有任務完成。

+0

@The_Black_Smurf不要電子書籍'中的應用。 DoEvents「(這裏有很多文章解釋了爲什麼它是一個壞主意)。這是多線程必須解決的典型問題。如果你想保持簡單並且只對兩個線程(GUI +所有計算)感興趣,你可以依靠'BackgrounWorker'。 – varocarbas

+0

它在多個線程(GUI +計算+數據庫操作)上運行,因此我創建了許多任務並等待它們完成。 – DrCocoa

+0

然後我不確定我是否理解你的問題。如果你有不同的線程,GUI肯定會更新(它不會被凍結)。你在問什麼時候應該向用戶顯示新信息?在最後還是中間?用您提供的信息非常難以分辨(=無);我想這是個人品味的問題(並且取決於你所談論的確切情況)請記住,SO是關於特定編程問題的具體問題(例如,我如何避免我的GUI被凍結?),不要討論抽象的建議。 – varocarbas

回答

0

你爲什麼不把你的例程放在Backgroundworker結構中?

因此,當您編寫過程數據代碼時,您已準備好更新您擁有的任何UI組件。

如果有必要,您也可以從Backgroundworker更新UI,但您需要有一些特殊要求才能做到這一點。

你可以諮詢在這裏: https://msdn.microsoft.com/en-us//library/ywkkz4s1.aspx

+0

請不要鏈接到外部資源,除非您在答案中包含鏈接頁面的詳細信息。此外,您已鏈接到葡萄牙語文檔。 – Enigmativity

+0

行動!我的錯......謝謝你的警告。但奇怪的是,這個頁面已經出現在英文中,就像我之前設定的那樣。無論如何,我將編輯答案中的鏈接。 –

0

首先,你需要建立一個委託,然後用Dispatcher.Invoke

在下面的例子中,一個按鈕從啓用更改爲禁用(或其他倒過來):

Delegate Sub SetRecordButtonEnabledCallback(ByVal Enabled As Boolean) 
    Friend Sub SetRecordButtonEnabled(ByVal Enabled As Boolean) 
     Me.btnDGRecord.IsEnabled = Enabled 
    End Sub 

後,所有你需要做的是從你的計時器中調用下面的代碼來調用它:

昏暗DesiredValue布爾=真

Me.Dispatcher.Invoke(新澤西SetRecordButtonEnabledCallback(AddressOf SetRecordButtonEnabled),新 對象(){DesiredValue})