使用RX c#批量更新UI



我在用RX更新WPF UI时遇到问题。目前,我有一个类,它有一个在其函数中调用的事件。事件是从UI线程订阅的,并更新UI,如下所示:

SomeClass.cs

public partial class SomeClass
{
public delegate Task ProgressUpdate(string value);
public delegate Task BarUpdate(int value);
public event ProgressUpdate OnProgressUpdateList;
public event BarUpdate OnProgressUpdateBar;
public async Task DoSomething() 
{
// execute code
<some code>
// update UI
if (OnProgressUpdateList != null)
{       
OnProgressUpdateList(update);             
}       
}
}

并且在MainWindow.xaml 中

var someClass = new SomeClass();
someClass.OnProgressUpdateList += Export_OnProgressUpdateList;
someClass.OnProgressUpdateBar += Export_OnProgressUpdateBar;

private async Task Export_OnProgressUpdateList(string text)
{
await Dispatcher.InvokeAsync(() =>
{
OutputLog.AppendText(text);
OutputLog.AppendText(Environment.NewLine);
OutputLog.ScrollToEnd();
});
}

除了程序处理大量文件外,这段代码还能正常工作,我想这就是UI很快冻结的原因(我看到更新在前半秒内完成(。我找到了解决这个问题的方法,并找到了一个使用RX来批处理UI调用的解决方案。我已经搜索了好几篇SO文章,但当我从类中调用这些事件并从该类外部订阅该事件时,我找不到关于如何正确实现这一点(或将C#事件转换为RX可观察性(的答案。有人能帮我理解吗?

我发布了一个答案给自己,因为我在这里找不到答案,我终于找到了,所以对于未来寻找答案的人来说——给你:

public partial class SomeClass {
public Subject<string> outputLogSubject = new Subject<string>();
public IObservable<string> OutputLog => outputLogSubject.AsObservable();
//Add string for collection updating UI
outputLogSubject.OnNext(string);

//After finishing the work you can call outputLogSubject.OnCompleted() to stop buffering
outputLogSubject.OnCompleted();
}

它需要添加到将调用执行工作的类中。

以下内容需要在初始化后和处理工作之前添加到UI线程中:

var buffer = someClass.OutputLog.Buffer(TimeSpan.FromMilliseconds(1000), 6);
var chunked = buffer.ObserveOnDispatcher(DispatcherPriority.Background);
var update = chunked.Subscribe(name =>
{
foreach (var item in name)
{
OutputLog.AppendText(item);
}
OutputLog.ScrollToEnd();
});

这使我能够使UI对看到输出日志是实时的点做出响应

最新更新