【发布时间】:2019-07-02 01:10:20
【问题描述】:
我有一个想法,就是创建一个可以等待的计时器,而不是引发事件。我还没有想到任何实际的应用程序,并且可能不是非常有用的东西,但我想看看它是否至少可以作为练习。可以这样使用:
var timer = new System.Timers.Timer();
timer.Interval = 100;
timer.Enabled = true;
for (int i = 0; i < 10; i++)
{
var signalTime = await timer;
Console.WriteLine($"Awaited {i}, SignalTime: {signalTime:HH:mm:ss.fff}");
}
定时器等待10次,预期输出为:
等待 0,信号时间:06:08:51.674
等待 1,信号时间:06:08:51.783
等待 2,信号时间:06:08:51.891
等待 3,信号时间:06:08:52.002
等待 4,信号时间:06:08:52.110
等待 5,信号时间:06:08:52.218
等待 6,信号时间:06:08:52.332
等待 7,信号时间:06:08:52.438
等待 8,信号时间:06:08:52.546
等待 9,SignalTime:06:08:52.660
在这种情况下,一个简单的await Task.Delay(100) 会做同样的事情,但是计时器可以灵活地控制程序另一部分的时间间隔(有可能thread safety issues 的警告)。
关于实现,我发现an article 描述了如何使各种事物等待,例如TimeSpan、int、DateTimeOffset 和Process。看来我必须编写一个返回TaskAwaiter 的扩展方法,但我不确定具体要做什么。有人知道吗?
public static TaskAwaiter GetAwaiter(this System.Timers.Timer timer)
{
// TODO
}
更新:我使用accepted answer执行的实际输出更新了示例代码和预期输出。
【问题讨论】:
-
@AlexeiLevenkov duplicate question 展示了如何使用
Task.Delay以预定义的时间间隔重复一个动作。在我的情况下,我想使用可以在应用程序执行期间动态控制(禁用、重新启用、更改间隔等)的Timer。我无法使用duplicate question 中提出的解决方案来解决我的问题。 -
它显示了实现完整类所需的所有信息(包括如何处理间隔变化......也许并不完全表明你可以使用几乎无限的间隔来
Enabled = false......但是这应该有点容易)。你应该edit这篇文章,并附上你在评论中提供的信息,以便重新打开它......但我担心它看起来像“为我写代码”(我肯定会这样看你问其他人进行编辑)。单独用于经过适当测试的生产就绪异步计时器的代码可能会突破 SO 答案的界限...... -
@AlexeiLevenkov 我的问题不是关于如何编写一个新类,而是关于如何通过实现扩展方法使现有的
System.Timers.Timer类可等待。这在我的问题中明确说明。你确定我可以通过应用重复问题的single answer 中提供的知识来实现这个目标吗?您可能会争辩说我的问题缺乏我的努力,但我向您保证,我确实在发布之前努力搜索重复... -
我想我理解你想要实现的目标,但它似乎也改变了计时器的整个前提(实际上它甚至不再是计时器)它是一个共享的 task.delay。这会更容易从头开始编写(IMO)。但是,您可能可以使用扩展方法和
TaskCompletionSource以及一些线程安全性来侥幸逃脱,尽管这似乎有点做作 -
@TheodorZoulias 抱歉,我完全误解了你的问题。现在我看到了你根据答案提出的问题......对我来说你为什么要这样做仍然没有意义......但我想你有你的理由。
标签: c# .net timer async-await