我使用MVVM。命令很慢。我想使用日志来指示执行的位置。 XAML:
<TextBlock Height="200" Text="{Binding Log.Content, UpdateSourceTrigger=PropertyChanged}"></TextBlock>
代码:
Log.addLine("Ledger initialized.");
// slow1 operation
Log.addLine("slow1 operation.");
只有在整个命令完成后才会更新文本块。当GUI处于活动状态时,两条消息都会同时出现。
答案 0 :(得分:0)
在这个例子中,我使用async / await来保持UI响应,以便它能够随时更新自己。 否则,在任何更新发生之前,必须完成长时间运行的任务。
由于长时间运行的任务在UI线程上(在您的示例中)已经同步,因此线程正在忙于执行您的方法,因此没有资源可用于刷新UI。执行该方法异步地在不同的线程上执行它,以便UI线程可以自由地执行UI相关操作,例如,渲染或更新绑定。
实施例
观点:
<Window x:Class="TestRange.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestRange"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:ViewModel x:Key="ViewModel" />
</Window.Resources>
<StackPanel DataContext="{StaticResource ViewModel}">
<Button Content="Long Running Task" Command="{Binding LongRunningCommand}" />
<TextBlock Text="{Binding Text}" />
</StackPanel>
</Window>
ViewModel:
class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
}
public ICommand LongRunningCommand => new RelayCommand(
async (param) => await this.LongRunningTaskAsync().ConfigureAwait(false), (param) => true);
public async Task LongRunningTaskAsync()
{
await Task.Run(
() =>
{
for (int i = 0; i < 3; i++)
{
Thread.Sleep(5000);
this.Text = $"Iteration #{i + 1} completed";
}
});
}
private string text;
public string Text
{
get { return this.text; }
set
{
this.text = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
答案 1 :(得分:-1)
尝试以异步方式执行慢速方法(可能是阻塞方法),如下所示:
Log.addLine("Ledger initialized.");
await Task.Run(() =>
{
SlowMethod();
});
Log.addLine("slow1 operation.");