我有一个WPF应用程序,将启动一个长时间运行的任务(60秒以上),该任务使用
在此假设下,我的研究表明,我可以使用
有人能给我一些见解,告诉我需要做什么才能使输出日志实时更新吗?以下是相关的代码片段。
XAML:
System.Reactive.Subject<string>
周期性地推送状态消息。我的想法是,我可以从ViewModel订阅可观察对象,并通过数据绑定使ReactiveUI自动更新我的UI。这一切都很好,但是TextBox只有在长时间运行的任务完成后才会实时更新。我认为这是因为我的UI线程被阻塞了,无法更新。在此假设下,我的研究表明,我可以使用
SubscribeOn
将订阅放在后台线程上,然后使用ObserveOnDispatcher
将通知推回UI线程。然而,这仍然没有产生我想要的结果--UI只在长时间运行的任务返回后更新。有人能给我一些见解,告诉我需要做什么才能使输出日志实时更新吗?以下是相关的代码片段。
XAML:
<TextBox Grid.Row="1" Text="{Binding Output}" IsReadOnly="True" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Margin="10,0,10,10" x:Name="OutputTextBox" />
代码后置:
protected override void OnContentRendered(EventArgs e)
{
if (Converter == null) return;
_viewModel = new ConversionOutputWindowViewModel(Converter);
DataContext = _viewModel;
_viewModel.StartConversion(); // Long-running Task
//_viewModel.StartSave();
FinishButton.IsEnabled = true;
}
视图模型:
private string _output;
public string Output // Data bound in XAML
{
get { return _output; }
set { this.RaiseAndSetIfChanged(ref _output, value); }
}
public void StartConversion()
{
_edmxConverter.Convert(); // Long-running Task
}
public ConversionOutputWindowViewModel(Utilities.Converters.EdmxConverter converter)
{
_edmxConverter = converter;
_compositeDisposable.Add(_edmxConverter.Output
.SubscribeOn(NewThreadScheduler.Default)
.ObserveOnDispatcher()
.Subscribe(s => Output = Output += s));
//_compositeDisposable.Add(_edmxConverter.Output.Subscribe(s => Output = Output += s));
}
长时间运行的任务函数:
public Subject<string> Output { get; }
Output = new Subject<string>(); //In ctor
private void PrintReplacement(XAttribute attribute, string oldValue, string newValue, int level, Verbosity minVerbosity = Verbosity.Informational)
{
if (Verbosity < minVerbosity) return;
Output.OnNext($"{new string('\t', level)}{attribute.Name}: {oldValue} -> {newValue}{Environment.NewLine}");
}
如果我把长时间运行的任务函数调用放在await Task.Run
里面,会不会有所帮助?我现在是试图寻找解决方法。我对.NET线程的工作原理了解不太深入。