【问题标题】:using timer objects dynamically c#/.net动态使用计时器对象 c#/.net
【发布时间】:2011-08-29 22:02:00
【问题描述】:

我想看看是否有人对动态使用计时器有任何经验或技巧。我们需要一个定期检查文本文件的 Windows 服务。文本文件将包含市场名称和开始时间。然后,该服务需要创建一个计时器来执行倒计时并将倒计时信息写入 xml 文件......比如 23 分钟

所有这些现在都可以在一个 Windows 应用程序上运行,用于一个计时器和一个倒计时......我们现在想要使这个动态......

所以当服务启动时,它会为每个市场/倒计时时间创建一个计时器...(例如凤凰城上午 10 点,芝加哥晚上 11:45 等)。

然后该服务将检查该文本文件中是否有任何新条目...因此,如果该文件包含 Phoenix、Chicago,然后添加了 New York,我们希望该服务保持 Phoenix 和 Chicago 计时器运行,然后启动一个纽约的计时器。

我只是不确定在一个服务下运行的多个计时器如何交互,以及当它们都需要写入同一个 xml 文件时线程将如何工作。

对此有什么想法吗?

【问题讨论】:

  • 您将不得不同步您的文件写入操作 - TextWriters、BinaryWriters 等都不是线程安全的。
  • 另外,如果有助于澄清一点;当你说你检查一个 XML 文件时,你是在说:从 XML 文件 A 加载数据,等待一段时间,然后写入 XML 文件 B 对吗?
  • @VulcanCCIT:您能否编辑您的问题以详细说明 Tejs 的问题?我无法给你一个可靠的答案,因为我不明白你的系统应该如何确切地工作。

标签: c# .net multithreading timer thread-safety


【解决方案1】:

我只是不确定在一个服务下运行的多个计时器如何交互,以及当它们都需要写入同一个 xml 文件时线程将如何工作。

对此有什么想法吗?

效果不好。

定时器在线程池中排队。线程池一次只会创建一定数量的活动线程:

http://msdn.microsoft.com/en-us/library/0ka9477y.aspx

可以排队到线程池的操作数量仅受可用内存的限制;但是,线程池限制了进程中可以同时处于活动状态的线程数

此外,从多个线程写入同一个文件会给您带来不好的结果。

更不用说,如果您让所有这些线程都在运行,那么弄清楚您的应用程序在做什么会更加困难。

更简单的方法

使用现有的计时器并在其上构建您自己的不使用线程的计时系统。

  • 创建一个定义倒计时条目的结构。

代码:

public class Countdown
{
    public DateTime Time { get; set; }
    public event Action Elapsed { get; set; }

    public void RaiseElasped()
    {
        if(Elapsed != null)
            Elapsed();
    }
}
  • 读取您的文件,然后创建:Dictionary<string, Countdown>(名称 -> 倒计时)。在每个动作中加入与计时器相同的代码。

  • 创建FileSystemWatcher 以查找对输入文件的更改。当文件被触发时,根据需要修改字典。

  • 创建一个分辨率为一分钟的计时器。

  • 每次触发计时器时,检查字典中的每个项目。如果目标时间已过,请致电RaiseElapsed。 (可能也将其从字典中删除?)

从这一点来看,很难确切地确定您想要做什么,因为您没有描述写入文件的内容、写入时间、频率或倒计时结束后会发生什么。不过,您应该能够自己解决剩下的问题。

这种方法的优点是单线程程序更容易调试,而且您不会遇到任何问题(并发文件访问或运行的线程过多)。

缺点是当你有很多条目时它可能会陷入困境。但是,如果您有很多条目,那么您真的应该使用数据库而不是文件。

【讨论】:

  • 我认为这会很好。在表单应用程序上,我正在写每个时区的经过时间(天,分钟,秒,直到倒计时截止日期)......在计时器的每 1 秒滴答声上......在倒计时结束时,计时器刚刚停止......所以是的,可能会把它从字典中拉出来……我试试看……我也喜欢 FileSystemWatcher 的想法。所以看起来我需要1个计时器,只是根据字典计算不同的“经过”时间,并将输出写入不同的文件......每个字典条目一个......
  • @VulcanCCIT:听起来这样可行,但我想就整体设计提供更多反馈。输入什么类型的时间 - 倒计时的总时间,或倒计时的目标时间?每个输出文件中将输出什么类型的时间?剩余时间?是什么消耗了该输出文件 - 倒计时应用程序本身?我问的原因是其中一些可能不是必需的。
【解决方案2】:

您可以维护拥有市场名称和时间的Dictionary<string,DateTime>。定期(比如每分钟?)您可以通过简单地使用 DateTime.Subtract() 扫描字典并计算经过的时间,并将结果写入输出文件。您可能还想查看Stopwatch class

【讨论】:

  • 是的,我也在考虑字典。我已经编写了所有计时器代码,但我担心多个计时器都写入同一个 xml 文件...
  • 实际上,这将是单独的 xml 文件......每个计时器都会写入自己的文件目录......所以这应该是线程明智的......所以我想我唯一剩下的担心是在服务中成为多个计时器(秒表类看起来不错!)
  • @VulcanCCIT:只做一个计时器(就像 ShitalShah 说的那样)。让该计时器触发字典中所有项目的倒计时处理。那么你就不用担心并发问题了。除非您拥有 大量 数据,否则您没有并行处理它们的事实并不是什么大问题。如果你有大量的数据,你需要使用一个数据库,而不是一个简单的文件。
  • @merlyn 需要多个计时器是倒计时时间可能不同......芝加哥可能需要从 7 月 1 日午夜开始倒计时......纽约可能需要倒计时时间直到新年, ...可以说,每个计时器都是一个单独的秒表。
  • @VulcanCCIT:您基本上是在单个“Timer”之上构建自己的计时器。我添加了自己的答案,详细说明了我在说什么。
猜你喜欢
  • 2010-11-15
  • 1970-01-01
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
  • 2011-01-25
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多