我想这可能会被标记为重复和封闭,但我一生都找不到这个问题的清晰、简洁的答案。所有的回复和资源几乎都专门处理 Windows 窗体并利用预构建的实用程序类,例如 BackgroundWorker。我非常想了解这个概念的核心,这样我就可以将基础知识应用到其他线程实现中。
我想要实现的一个简单示例:
//timer running on a seperate thread and raising events at set intervals
//incomplete, but functional, except for the cross-thread event raising
class Timer
{
//how often the Alarm event is raised
float _alarmInterval;
//stopwatch to keep time
Stopwatch _stopwatch;
//this Thread used to repeatedly check for events to raise
Thread _timerThread;
//used to pause the timer
bool _paused;
//used to determine Alarm event raises
float _timeOfLastAlarm = 0;
//this is the event I want to raise on the Main Thread
public event EventHandler Alarm;
//Constructor
public Timer(float alarmInterval)
{
_alarmInterval = alarmInterval;
_stopwatch = new Stopwatch();
_timerThread = new Thread(new ThreadStart(Initiate));
}
//toggles the Timer
//do I need to marshall this data back and forth as well? or is the
//_paused boolean in a shared data pool that both threads can access?
public void Pause()
{
_paused = (!_paused);
}
//little Helper to start the Stopwatch and loop over the Main method
void Initiate()
{
_stopwatch.Start();
while (true) Main();
}
//checks for Alarm events
void Main()
{
if (_paused && _stopwatch.IsRunning) _stopwatch.Stop();
if (!_paused && !_stopwatch.IsRunning) _stopwatch.Start();
if (_stopwatch.Elapsed.TotalSeconds > _timeOfLastAlarm)
{
_timeOfLastAlarm = _stopwatch.Elapsed.Seconds;
RaiseAlarm();
}
}
}
这里有两个问题;主要是,我如何将事件发送到主线程以提醒有关方警报事件。
其次,关于 Pause() 方法,该方法将由运行在主线程上的对象调用;我可以通过调用 _stopwatch.start()/_stopwatch.stop() 直接操作在后台线程上创建的秒表吗?如果没有,主线程是否可以如上所示调整 _paused 布尔值,以便后台线程可以看到 _paused 的新值并使用它?
我发誓,我已经完成了我的研究,但是这些(基本的和关键的)细节还没有让我清楚。
免责声明:我知道有可用的类将提供我在 Timer 类中描述的确切特定功能。(事实上,我相信这个类就是这样命名的,Threading.Timer)但是,我的问题不是试图帮助我实现 Timer 类本身,而是理解如何执行驱动它的概念。