誰能教我UI凍結爲什麼UI繁重的計算期間凍結:MvvmCross - 當我打電話Task.Run
var ret = await Task.Run(() => this._service.CalcFourier(100000, progress));
我有是有約束力的「值」屬性的進度條,但其棒沒有更新,直到計算完了。當我將斷點設置爲'CurrentCalcCount'的setter方法並開始計算時,每次都會調用'RaisePropertyChanged'。
如何避免阻塞用戶界面...我一整天都在工作,我不知道爲什麼。任何機構都可以修復代碼或有一些解釋來幫助我?謝謝。
CalcView.xaml
<Grid Grid.Row="0">
<TextBlock Text="Calculate pi with fourier transform method." Margin="3" />
</Grid>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="Calc time:" Margin="3" VerticalAlignment="Center"/>
<TextBox Text="{Binding CalculationCount, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" MinWidth="150" Margin="3"/>
<Button Content="Start" Margin="3,0,3,3" Command="{Binding CalcCommand}" />
</StackPanel>
<StackPanel Grid.Row="2">
<ProgressBar MinHeight="25" Margin="5" Maximum="{Binding CalculationCount}" Value="{Binding CurrentCalcCount}" />
<Button Content="Cancel" MaxWidth="100" Command="{Binding CancelCommand}"/>
</StackPanel>
<TextBlock Grid.Row="3" Text="{Binding ProgressText}" HorizontalAlignment="Center"/>
'CalcCommand' 和其它性質定義如下:
CalcViewModel.cs在模型
private MvxCommand _calcCommand;
public ICommand CalcCommand
{
get
{
return _calcCommand ??
(_calcCommand = new MvxCommand(DoCalcCommand,() => !InProgress));
}
}
private async void DoCalcCommand()
{
try
{
InProgress = true;
var progress = new Progress<CalcProgressInfo>(info => Dispatcher.RequestMainThreadAction(() =>
{
CurrentCalcCount = info.CurrentCount;
ProgressText = info.Message;
}));
var ret = await Task.Run(() => this._service.CalcFourier(this._calculationCount, progress));
ProgressText += Environment.NewLine + ret;
}
catch (Exception e)
{
ProgressText = e.Message;
}
finally
{
InProgress = false;
}
}
CalcFourier命令:
CalcService。 cs
private bool _cancel;
public double CalcFourier(int count, IProgress<CalcProgressInfo> progress)
{
var sigma = 0.0;
var n = 1;
foreach (
var i in
Enumerable.Range(1, count).TakeWhile(_ => !_cancel))
{
progress.Report(new CalcProgressInfo(i,
string.Format("Calculation is in progress now. - {0}/{1}", i, count)));
sigma += 1.0/n/n;
n += 2;
}
progress.Report(this._cancel
? new CalcProgressInfo(0, "Calculation has canceled.")
: new CalcProgressInfo(count, "Calculation has completed."));
_cancel = false;
return Math.Sqrt(sigma * 8);
}
看看MSDN上的【如何調用Visual C#方法異步(http://support.microsoft.com/kb/315582)頁面。 – Sheridan
我認爲它凍結,因爲你正在等待這個過程,因爲它是你的'命令'的一部分,所以而不是[await](http://msdn.microsoft.com/en-us/library/hh156528.aspx) 你可以試試[BackgroundWorker(http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx) – WiiMaxx
我想我現在就明白了。我將繼續學習異步模式。謝謝。 – ailen0ada