gpt4 book ai didi

java - C#语言等同于ScheduledExecutorService

转载 作者:搜寻专家 更新时间:2023-10-31 20:28:08 26 4
gpt4 key购买 nike

我正在使用具有 C# API 的 RF 读取器设备。根据其 API,您需要手动调用其读取功能来读取/标记卡片。

所以我的解决方法是使用 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() 等效的解决方法。

我希望有解决此问题的方法,因为我尽快需要它。

谢谢!

最佳答案

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

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 毫秒减去执行扫描函数所花费的时间后被调用。像这样设置,您可能会从扫描中删除 sleep 。

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

另一种解决方案可能是根本不使用计时器。只需循环并使用秒表来计算 sleep 时间:

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);
}
}

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

关于java - C#语言等同于ScheduledExecutorService,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25668719/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com