[英]Progress bar in WPF MVVM and TPL dataflow
我在遵循 MVVM 模式的 WPF 應用程序中使用 TPL 數據流。 我有一個TransformBlock<object,object>
和一個ActionBlock<object>
,我像這樣鏈接它們:
transformBlock.LinkTo(notificationBlock);
ActionBlock<object>
應該使用當前進度更新我視圖中的進度條,但 UI 似乎被凍結,並且只有在一切都完成處理后才會更新。
我的CurrentProgress
屬性如下所示:
private double _CurrentProgress;
public double CurrentProgress
{
get { return _CurrentProgress; }
set
{
_CurrentProgress = value;
RaisePropertyChanged("CurrentProgress");
}
}
我將它綁定到我的視圖,如下所示:
<ProgressBar Value="{Binding CurrentProgress, Mode=OneWay}" Name="uxProgressBar"/>
我錯過了什么嗎? 為什么 TPL 會阻塞 UI 線程?
編輯
這就是我實例化 TPL 的方式:
foreach(var myObj in ObjList)
{
transformBlock.Post(myObj);
}
轉換塊:
TransformBlock<object, object>(
temp =>
{
var response = ProcessRecord(temp);
return response.Status;
},
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism =20
});
動作塊:
ActionBlock<object>(
temp =>
{
CurrentProgress = (double)temp.RecordNumber/(double)TotalRecords;
},
new ExecutionDataflowBlockOptions
{
TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext()
});
更新
在TransformBlock
中調用的 web 服務是一個遺留 (asmx) web 服務,它沒有被稱為Async
。 解決此問題后,其他一切正常,無需使用Dispatcher
或任何其他建議的解決方案。
從評論之一到問題,似乎 WPF 確實支持從另一個線程發布到 UI 線程。 不過,我還沒有找到任何關於此的官方文檔。
嘗試使用“SendAsync”將您的代碼發布到 TransformBlock:
foreach (var myObj in ObjList)
{
await transformBlock.SendAsync(myObj);
}
首先,您的ActionBlock
不必直接更改CurrentProgress
屬性。
原因是RaisePropertyChanged
函數會直接運行ProgressBar
對象的代碼。 這是不允許的,因為它是 UIThread 擁有的對象。
ActionBlock
在他自己的線程中運行,他需要將 progressBar 更新順序發布到 UI 線程(通過使用Dispatcher.BeginInvoke
):
ActionBlock<object>(
temp =>
{
double progress = (double)temp.RecordNumber/(double)TotalRecords;
Dispatcher.BeginInvoke((Action)(() =>
{
CurrentProgress = progress;
}));
},
new ExecutionDataflowBlockOptions
{
TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext()
});
你必須改變這第一件事,才能做出你想要的。
其次(如果這不會改變任何東西),您必須檢查您的 UI 線程是否沒有等待TransformBlock
的完成。 如果您的ICommand
(例如,如果您從按鈕調用它)不是 ASync 並執行以下操作:
transformBlock.Completion.Wait();
不行。 因為你的 UIThread 會等待你的處理結束,直到結束才會接之前的progressBar更新命令。
祝你好運 ! 如果它總是不起作用,請發布新的詳細信息。
您應該使用Dispatcher
通知 UI 線程您要從后台進程更新綁定值。
這是一篇解釋文章的鏈接:
http://msdn.microsoft.com/en-us/magazine/cc163328.aspx
http://msdn.microsoft.com/en-us/library/vstudio/system.windows.threading.dispatcher
我將整理一個類似的代碼示例並很快更新此響應。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.