0

我目前在 XAML 中使用 valueconverters 以“x 分钟前”格式显示我的视图模型 DateTime 字段。我需要定期更新它们而不会造成太多开销。在任何时候,我都有十几个在屏幕上,几十个在屏幕外。什么是最好的策略?

  1. 在 viewmodel 对象的构造函数中,让它们将自己注册到静态“ViewRefresher”,该静态“ViewRefresher”会定期遍历所有对象并在注册字段上触发 PropertyChanged 处理程序。

  2. 刷新包含我的对象的内容/项目控制对象

  3. 还有什么?

我将继续尝试上述两种方法,同时等待答案并报告,以防它帮助其他人。

更新: 好的,感谢 csteinmueller 将我置于事件路径上。比注册/注销对象要干净得多。我相信以下策略不应该泄漏。

public class DateTimeC: INotifyPropertyChanged
{
    public DateTime DT {get; set;}
    public event PropertyChangedEventHandler PropertyChanged;

    public DateTimeC(DateTime dt)
    {
        DT = dt;
        ViewRefresher.FiveSecondsTick += () =>
           { PropertyChanged(this, new PropertyChangedEventArgs("DT")); };
    }

}

public delegate void TickHandler();

public static class ViewRefresher
{
    private static DispatcherTimer dt = new DispatcherTimer();
    private static int counter = 0;

    public static event TickHandler FiveSecondsTick;
    public static event TickHandler OneMinuteTick;

    static ViewRefresher()
    {
        dt.Interval = TimeSpan.FromSeconds(5);
        dt.Tick += Tick;
        dt.Start();
    }

    private static void Tick(object sender, EventArgs e)
    {
        if (FiveSecondsTick != null)
            FiveSecondsTick();

        if (counter++ != 12) return;

        counter = 0;

        if (OneMinuteTick != null)
            OneMinuteTick();
    }
}

如果我可以直接从 DateTime 派生而不是作为字段内联,那就太好了,但它是密封的。

更新 2:这似乎确实有内存泄漏。您需要取消挂钩事件以将 DateTimeC 进行垃圾收集,或使用弱引用。

4

1 回答 1

1

我会选择一个 System.Timer 对象以及您的第一种方法(所有 ViewModel 都注册到静态类中的集合或事件)

Timer timer;
AutoResetEvent autoEvent = new AutoResetEvent(true);
TimerCallback callback = new TimerCallback(MyCallback);

timer = new Timer(callback, autoEvent, new TimeSpan(0), new Timespan(5));
于 2012-05-23T09:20:19.577 回答