我目前正在從一個大的二進制文件中讀取應用程序,該文件包含數千個文件,每個文件正由應用程序中的其他類處理。該類返回一個對象或null。我想在主表單上顯示進度,但出於某種原因,我無法理解它。FromCurrentSynchronizationContext,我錯過了什麼?
int TotalFound = 0;
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext;
BufferBlock<file> buffer = new BufferBlock<file>();
DataflowBlockOptions options = new DataflowBlockOptions(){ TaskScheduler = uiScheduler, };
var producer = new ActionBlock<someObject>(largeFile=>{
var file = GetFileFromLargeFile(largeFile);
if(file !=null){
TotalFound++;
buffer.post(file);
lblProgress.Text = String.Format("{0}", TotalFound);
}
}, options);
上面的代碼凍結我的表,甚至我用「TaskScheduler.FromCurrentSynchronizationContext」,爲什麼呢?因爲當我用我下面的表格,代碼將更新精細
DataflowBlockOptions options = new DataflowBlockOptions(){ TaskScheduler = uiScheduler, };
var producer = new ActionBlock<someObject>(largeFile=>{
var file = GetFileFromLargeFile(largeFile);
if(file !=null){
Task.Factory.StartNew(() => {
TotalFound++;
buffer.Post(file);
}).ContinueWith(uiTask => {
lblProgress.Text = String.Format("{0}", TotalFound);
},CancellationToken.None, TaskContinuationOptions.None, uiScheduler);
}
});
我是新來這整個TPL數據流,所以我希望有人能分享爲什麼在第二代碼片段它的工作原理,並在第一個片段的一些光它沒有。
親切的問候, 馬亭
TNX的解釋,明確給我認識。仍然有一個問題,像在第一個例子中那樣在UI線程外部運行任務會更好嗎?我們這樣做對於應用程序的性能無關緊要嗎? – Martijn
如果任務只運行很短的時間,那麼它並不重要。否則,你不應該在UI線程上運行長時間運行的任務。不是因爲性能,而是因爲它會凍結你的應用程序。 – svick
是否有任何其他(更好)的方式來處理gui更新?我使用svick推薦的代碼,但仍然是我的UI凍結..在我的應用程序中,總共有8個ActionBlock每個執行一個自定義對象的任務,3個ActionBlocks執行有一個MaxParallizism設置爲處理器計數,在我的情況是7.所有8個ActionBlocks與gui進行通信......因此,理論上它可能是> 30個想要更新gui的任務。任何想法? –
Martijn