2014-09-04 35 views
5

我正在使用具有C#API的RF阅读器设备。基于它的API,您需要手动调用其读取函数来读取/标记卡。相当于ScheduledExecutorService的C#语言

所以我的解决方法是使用Timer来执行读取每'n'秒。

我的问题是Timer不断执行,不管Thread.sleep()是否在它的动作中被调用。

Timer timer = new Timer(TimerCallback, null, 500, 1000); // From main() method 

// The action that Timer executes 
private void TimerCallback(Object o) 
{ 
    scan(); // Action for reading/badging card 
    scand.WaitOne(); // AutoResetEvent(true) 
    GC.Collect(); // Force garbage collection 
} 

Thread.sleep()在scan()中调用。

在Java中,我使用synchronized()来等待其他线程调用invoke()。我搜索了整整一天,但无法看到等效于ScheduledExecutorService和synchronized()的解决方法。

我希望有一个解决方法,这个原因我需要它尽快。

谢谢!

+0

没有你看看Task类? http://stackoverflow.com/questions/13211334/how-do-i-wait-until-task-is-finished-in-c – fuchs777 2014-09-04 15:22:08

+0

我看到任务类,当我正在搜索,但代码@Erno de Weerd给予解决我的问题。 但无论如何。 – 2014-09-05 12:56:58

回答

2

我能找到的最可靠的方法是在回调中重新启动计时器。这样回调不会在活动时中断。

Timer timer = new Timer(TimerCallback, null, 500, 0); 

private void TimerCallback(Object o) 
{ 
    scan(); 
    scand.WaitOne(); 
    timer.Change(500, 0); 
} 

timer.Change重新安排定时器。

注意:我删除了定时器启动时的重复。

顺便说一句:我删除了GC.Collect(),因为我认为这种做法不好,在大多数情况下无用。

此外,你可以在方法的开始(使用Stopwatch)获得的时间和计算所需的时间差将被传递给timer.Change:

Timer timer = new Timer(TimerCallback, null, 500, 0); 
Stopwatch stopwatch = Stopwatch.StartNew(); 

private void TimerCallback(Object o) 
{ 
    var entered = stopwatch.ElapsedMilliseconds; 
    scan(); 
    scand.WaitOne(); 
    var duration = stopwatch.ElapsedMilliseconds - entered; 
    var delay = Math.Max(0, 500 - duration); 
    timer.Change(delay, 0); 
} 

这样的回调将500之后调用ms减去执行扫描功能所用的时间。像这样设置,你可以从扫描中删除睡眠。

您的代码中的双重回调的原因可能是计时器在第一个线程仍在执行回调时在另一个线程上执行回调。

另一种解决方案可能是根本不使用定时器。只是环和使用秒表来计算时间进入睡眠状态:

private void Scan() 
{ 
    while(scanning) 
    { 
     var entered = stopwatch.ElapsedMilliseconds; 
     scan(); 
     scand.WaitOne(); 
     var duration = stopwatch.ElapsedMilliseconds - entered; 
     var delay = Math.Max(0, 500 - duration); 
     Thread.Sleep(delay); 
    } 
} 

确保你调用这个方法在一个单独的线程(你可以使用一个任务)

+0

感谢您的简短回复。你的正确,我的问题是,我现有的代码导致无尽的延期回调。你的第二个图解代码是我使用的代码,它可以按我的要求完美工作。你推荐'timer.Change()'做了诀窍。 谢谢! – 2014-09-05 12:55:23