【发布时间】:2014-02-08 13:10:01
【问题描述】:
在我的 WPF 应用程序中,UI 显示的数据更新得太频繁了。 我发现保持逻辑不变并通过一个额外的类来解决这个问题会很棒,该类存储最新的数据并在一些延迟后引发更新事件。
所以目标是更新 UI,假设每 50 毫秒,并显示最新数据。但如果没有新数据要显示,则 UI 不会更新。
这是我迄今为止创建的一个实现。有没有不加锁的方法?我的实现是否正确?
class Publisher<T>
{
private readonly TimeSpan delay;
private readonly CancellationToken cancellationToken;
private readonly Task cancellationTask;
private T data;
private bool published = true;
private readonly object publishLock = new object();
private async void PublishMethod()
{
await Task.WhenAny(Task.Delay(this.delay), this.cancellationTask);
this.cancellationToken.ThrowIfCancellationRequested();
T dataToPublish;
lock (this.publishLock)
{
this.published = true;
dataToPublish = this.data;
}
this.NewDataAvailable(dataToPublish);
}
internal Publisher(TimeSpan delay, CancellationToken cancellationToken)
{
this.delay = delay;
this.cancellationToken = cancellationToken;
var tcs = new TaskCompletionSource<bool>();
cancellationToken.Register(() => tcs.TrySetCanceled(), useSynchronizationContext: false);
this.cancellationTask = tcs.Task;
}
internal void Publish(T data)
{
var runNewTask = false;
lock (this.publishLock)
{
this.data = data;
if (this.published)
{
this.published = false;
runNewTask = true;
}
}
if (runNewTask)
Task.Run((Action)this.PublishMethod);
}
internal event Action<T> NewDataAvailable = delegate { };
}
【问题讨论】:
-
您的数据来自哪里?您是否愿意丢失旧的部分,而不是最近的部分?
-
数据来自任务(确切地说是包装的 WebClients)。我完全可以丢失旧件 - 这只是为了显示当前状态。
标签: c# wpf asynchronous