我的WPF/C#程序使用在特定序列中調用的不同方法。 每種方法都綁定到UI,在長時間處理後顯示一些數據。 我正在使用調度程序,導致被調用的方法在另一個線程中。 我也希望在不凍結UI的情況下執行此過程,例如可以取消過程並自由移動窗口。長進程,綁定更新和UI凍結
我的問題是根本沒有更新用戶界面(進度條,計算步驟),取消按鈕在計算結束後纔會運行。 事實上,即使掛起的長期過程沒有完成,也不知道如何立即取消一般序列。
我不是100%肯定會使用正確的方式,有沒有人有更好的解決方案或任何建議?
ex。
public void CalculationCommand()
{
var bkw = new BackgroundWorker()
bkw.DoWork += Work;
bkw.RunWorkerAsync(Dispatcher.CurrentDispatcher);
}
public void Work(object sender, DoWorkEventArgs e)
{
var dispatcher = e.Argument as Dispatcher;
var dispatcherPriority = DispatcherPriority.Background;
Action action;
action =() =>
{
UpdateStatut(StatutsInformation.Pending);
};
dispatcher.BeginInvoke(action, dispatcherPriority);
ViewModel1 viewModel1 = null;
action =() =>
{
UpdateProgress(10, "Sampling calculations");
viewModel1 = Application.GetEchantillonnage();//Long process
};
dispatcher.BeginInvoke(action, dispatcherPriority);
List<double> lengthList = null;
action =() =>
{
UpdateProgress(20, "Length calculations");
lengthList = AlgorithmLibrary.LengthCalculations(viewModel1);//Long process
};
dispatcher.BeginInvoke(action, dispatcherPriority);
ViewModel2 viewModel2 = null;
action =() =>
{
UpdateProgress(30, "Engine calculations");
viewModel2 = Application.GetEngine();//Long process
AlgorithmLibrary.EngineCalculations(viewModel2);//Long process
var FilteredLength = AlgorithmLibrary.LengthFilter(lengthList);//Long process
}; dispatcher.BeginInvoke(action, dispatcherPriority);
///... Others actions executed incrementing the progress value to 100%
action =() =>
{
UpdateStatut(StatutsInformation.Finished);
};
dispatcher.BeginInvoke(action, dispatcherPriority);
}
private void UpdateStatut(StatutsInformation statutInformation)
{
ViewModelLoading.StatutInformation = statutInformation;
}
private void UpdateProgress(int value, string label)
{
ViewModelLoading.Progress = value;
ViewModelLoading.Step = label;
}
感謝
這裏的問題是,調用「viewModel1 = Application.GetEchantillonnage()」給出錯誤: – midget
「因爲不同的線程擁有它調用線程不能訪問此對象」 @midget你正在做一些觸及界面的'GetEchantillonnage'方法。我不知道什麼或爲什麼,但你不需要那樣做。如果'GetEchantillonnage'需要來自用戶界面的東西,那麼**當你仍然在UI線程中時,首先獲取這些信息。然後重構此方法,以便在調用它時獲取此信息,並將整個事件移出Application對象。 – Will
MVVM模式的重要組成部分是***將業務邏輯從用戶界面***中分離出來。如果你這樣做,那麼你沒有問題。但是你仍然將它們混合在一起('Application'沒有本地的'GetEchantillonnage'方法 - 你把它放在那裏)。重構刪除它。 – Will