【发布时间】:2014-05-15 16:02:44
【问题描述】:
我在我的应用程序中使用System.Timers.Timer。每一秒我都会运行一个函数来完成一些工作。问题是,这个函数可以阻塞一小段时间(它从磁盘读取然后处理一个大文件)。只有在其先前的“执行实例”完成时,我才想启动该功能。我以为我可以通过Mutex 实现这一点:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static Mutex TimerMut = new Mutex(false);
public static void Main()
{
Thread TT = new Thread(new ThreadStart(delegate()
{
System.Timers.Timer oTimer = new System.Timers.Timer();
oTimer.Elapsed += new ElapsedEventHandler(Handler);
oTimer.Interval = 1000;
oTimer.Enabled = true;
}));
TT.Start();
Console.Read();
}
private static void Handler(object oSource,
ElapsedEventArgs oElapsedEventArgs)
{
TimerMut.WaitOne();
Console.WriteLine("foo");
Thread.Sleep(500); //simulate some work
Console.WriteLine("bar");
TimerMut.ReleaseMutex();
}
}
}
那不行,“foos”仍然每秒出现一次。我怎样才能做到这一点?
编辑:你是对的,启动一个新线程来处理这个是没有意义的。我以为只有System.Threading.Timer 在单独的线程中启动。
【问题讨论】:
-
我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
-
也许 foo 每秒出现一次,因为你的模拟工作只持续半秒。但是,这种方法的问题在于,如果前一个实例正在运行,则 Handler 需要退出而不做任何事情。您的代码正在等待前一个代码完成,然后继续。如果您的工作需要 20 秒,那么将有 20 次对 Handler 的调用等待互斥体并在前一个退出时继续执行工作。
-
您的代码甚至不应该编译。您已经在方法中声明了一个静态变量……这意味着您正在运行的代码不是您向我们展示的代码。请制作一个简短但完整的程序来演示该问题。
-
@szczurcio:好的,那么现在你能把它变成一个完整的例子吗?我们应该可以复制、粘贴、编译、运行、观察问题。