我没有手动摆弄DispatcherTimer,而是想出了这个:
public async void StartWatching()
{
Debug.Assert(SynchronizationContext.Current is DispatcherSynchronizationContext, "SynchronizationContext.Current is DispatcherSynchronizationContext");
while ( true )
{
this.GC0 = GC.CollectionCount(0);
this.GC1 = GC.CollectionCount(1);
this.GC2 = GC.CollectionCount(2);
this.RAM = GC.GetTotalMemory(false);
await Task.Delay(1500);
}
}
此代码与垃圾收集无关,只是在状态栏上显示统计信息。
这一次开始(从Application.OnStartup
开始)并且打算在整个应用程序运行时运行。
长期运行(周)会让我遇到任何麻烦吗?
答案 0 :(得分:2)
长期运行(周)会让我遇到任何麻烦吗?
不是真的。但是有一些事情需要注意。
由于您的方法返回async void
,因此将直接在方法开头的当前SynchronizationContext
上引发任何异常。因此,他们将直接进入调度程序(或WinForms的应用程序)。听起来这种行为可能是你想要的。
延迟工作与使用周期性计时器不同,特别是如果工作可能需要不同的时间。所以,这段代码不会每1.5秒运行一次;它会比那个少一点。但是,这样做的好处就是你不必担心代码重叠,就像使用纯周期定时器一样。
还会有更多的“抖动”。在幕后发生的事情是Task.Delay
启动线程池计时器,当它触发时,它将完成任务;此时,StartWatching
的延续已安排到UI线程,并且在执行其工作之前,它将耐心地等待UI线程空闲。所以会有一个额外的“等待UI线程”需要花费不同的时间 - 通常是立即的,但有时候等待所有的UI绑定更新,...
最后,非常小的延迟可能效果不佳。 WinForm和Dispatcher定时器使用更高级的机制(内置于其消息循环中)以获得更高的准确性。由于Task.Delay
的额外开销,我相信在现实世界的应用程序中,它不适用于非常小的延迟。 (这只是一种直觉,而不是测试的结果)。
答案 1 :(得分:1)
就个人而言,与使用DispatcherTimer
相比,我认为这种方法没有什么特别糟糕的。就我个人而言,我也使用过这种方法 - 它非常简短,直截了当。
但是,请注意async
方法不会使您的应用程序崩溃 - 它们会在您不知情的情况下无声地死亡。因此,您需要捕获您可以想到的所有可能的异常。此外,finally
方法中的任何async
块都不会运行。您还应该考虑为其添加CancellationToken
。
对于您的情况,我认为这不会导致问题。