异步友好 DispatcherTimer 包装器/子类 [英] Async friendly DispatcherTimer wrapper/subclass
本文介绍了异步友好 DispatcherTimer 包装器/子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个 DispatcherTimer
在我的代码中运行,它每 30 秒触发一次以从服务器更新系统状态.即使我正在调试我的服务器代码,计时器也会在客户端触发,所以如果我已经调试了 5 分钟,我可能会在客户端出现十几个超时.最后决定我需要解决这个问题,所以希望制作一个更async
/await
友好的 DispatcherTimer.
I have a DispatcherTimer
running in my code that fire every 30 seconds to update system status from the server. The timer fires in the client even if I'm debugging my server code so if I've been debugging for 5 minutes I may end up with a dozen timeouts in the client. Finally decided I needed to fix this so looking to make a more async
/ await
friendly DispatcherTimer.
- 在
DispatcherTimer
中运行的代码必须是可配置的,无论它是否可重入(即,如果任务已经在运行,则不应尝试再次运行它) - 应该是基于任务的(无论这是否需要我在根部实际暴露任务是一个灰色区域)
- 应该能够运行异步代码并
await
完成任务 - 它是否包装或扩展 DispatcherTimer 可能并不重要,但如果您不知道如何使用它,包装它可能会稍微不那么模糊
- 可能为 UI 公开
IsRunning
的可绑定属性
- Code running in
DispatcherTimer
must be configurable whether it is reentrant or not (i.e. if the task is already running it should not try to run it again) - Should be task based (whether or not this requires I actually expose Task at the root is a gray area)
- Should be able to run async code and
await
on tasks to complete - Whether it wraps or extends DispatcherTimer probably doesn't really matter but wrapping it may be slightly less ambiguous if you don't know how to use it
- Possibly expose bindable properties for
IsRunning
for UI
推荐答案
这是我的想法.
SmartDispatcherTimer
扩展DispatcherTimer
(这是启动和运行的最简单方法)- 有一个
TickTask
属性来提供一个Task
来处理逻辑 - 有一个
IsReentrant
属性(当然,重点是我希望它不是可重入的,所以通常这是错误的) - 它假设您调用的任何内容都是完全可等待的 - 否则您最终将失去重入保护的好处
SmartDispatcherTimer
ExtendsDispatcherTimer
(was easiest way to get this up and running)- Has a
TickTask
property to provide aTask
to handle the logic - Has an
IsReentrant
property (of course the whole point is that I want it to not be reentrant so normally this is false) - It assumes anything you're calling is fully awaitable - or you'd end up losing the reentrancy protection benefits
用法:
var timer = new SmartDispatcherTimer();
timer.IsReentrant = false;
timer.Interval = TimeSpan.FromSeconds(30);
timer.TickTask = async () =>
{
StatusMessage = "Updating..."; // MVVM property
await UpdateSystemStatus(false);
StatusMessage = "Updated at " + DateTime.Now;
};
timer.Start();
这是代码.很想听听关于它的任何想法
Here's the code. Would love to hear any thoughts on it
public class SmartDispatcherTimer : DispatcherTimer
{
public SmartDispatcherTimer()
{
base.Tick += SmartDispatcherTimer_Tick;
}
async void SmartDispatcherTimer_Tick(object sender, EventArgs e)
{
if (TickTask == null)
{
Debug.WriteLine("No task set!");
return;
}
if (IsRunning && !IsReentrant)
{
// previous task hasn't completed
Debug.WriteLine("Task already running");
return;
}
try
{
// we're running it now
IsRunning = true;
Debug.WriteLine("Running Task");
await TickTask.Invoke();
Debug.WriteLine("Task Completed");
}
catch (Exception)
{
Debug.WriteLine("Task Failed");
}
finally
{
// allow it to run again
IsRunning = false;
}
}
public bool IsReentrant { get; set; }
public bool IsRunning { get; private set; }
public Func<Task> TickTask { get; set; }
}
这篇关于异步友好 DispatcherTimer 包装器/子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文