感謝Noseratio的建議,我實際上重新設計瞭如何做到這一點,並能夠沒有問題地工作。我刪除了BackgroundWorker
的對象,因爲它不是真的有必要。相反,我將整個數據流封裝在異步方法中,該方法將各種Progress<T>
參數用作進度更新的回調。由於Progress<T>
的Report()
方法在預先存在的塊中調用,因此沒有使用額外的TPL塊來發布進度。此外,由於這是一個異步函數,表示數據流的任務不在UI線程上運行,而是在線程池線程上運行。由此可見,Progress<T>
對象的回調會在創建它們的線程上運行,因爲在構建期間它們會捕獲當前的同步上下文。以下是對解決我的問題的例子:
public static async Task ProcessData(IProgress<int> ReadProg, IProgress<int> UploadProg)
{
var loadBuffer = new BufferBlock<string>();
var parseBlock = new TransformBlock<string, MyObject>(async s =>
{
if(await DoSomething(s))
ReadProg.Report(1);
else
ReadProg.Report(-1);
});
...
//setup of other blocks
//link blocks
//feed data into pipeline by adding data into the head block: loadBuffer
//await ALL continuation tasks of the blocks
}
然後在UI中,我創建了Progress<int>
對象,並通過他們到異步ProcessData
方法。無論何時在異步處理方法中調用Process<T>.Report()
方法,UI均會更新而不會出現問題。
您是否在使用'DataflowBlockOptions.TaskScheduler'使其運行UI線程?一段代碼會有幫助。 – Noseratio
@Noseratio這更多的是一個理論問題。我仍然計劃這個功能。截至目前,它沒有報告進展情況。使用'DataflowBlockOptions.TaskScheduler'是我如何告訴那些特定的塊在UI線程上運行。 – JNYRanger
我會使用'Progress'模式,並沒有訴諸UI線程TaskScheduler。 –
Noseratio