如何使用 System.Threading.Timer c# 在同一线程上运行代码
Posted
技术标签:
【中文标题】如何使用 System.Threading.Timer c# 在同一线程上运行代码【英文标题】:How do run code on the same thread with System.Threading.Timer c# 【发布时间】:2020-06-23 20:49:05 【问题描述】:我有一个应用程序,它应该每隔几秒钟运行一个方法,但要等到上一次运行完成。我已经通过在metod运行之前禁用计时器来解决这个问题,如下面的代码所示。我怀疑无论如何都会不时调用另一个线程。我想在同一个线程上运行所有内容。关于如何使用 system.threading.timer 的任何想法?
提前致谢。
timer = new System.Threading.Timer((e) =>
Console.WriteLine("*** Running Code *** ");
Console.WriteLine(DateTime.Now);
timer.Change(Timeout.Infinite, Timeout.Infinite);
MyMethod();
timer.Change(periodTimeSpanGet,periodTimeSpanGet);
Console.WriteLine("*** Code Finished Code *** ");
Console.WriteLine(DateTime.Now);
, null, startTimeSpan, periodTimeSpanGet);
`
【问题讨论】:
为什么“在同一个线程上”?这会带来什么好处?定时器回调发生在线程池中,所以不一定在同一个线程上。 使用SynchronizationContext
Post 或 Send(假设你试图编组的线程不是线程池并且支持这个)
看来您的问题是不需要的并发性(重叠执行),而不是每次执行都可能发生在不同的线程中。第二个问题的解决方案也是第一个问题的解决方案,但可能不是最佳解决方案。
谢谢。如何解决不需要的并发?
您可以通过等待Task.Delay
或SemaphoreSlim
的WaitAsync
方法以初始计数= 1 实例化,轻松解决不必要的并发问题。您的问题已经有了很好的答案你想要的,但不是你在标题中要求的!
【参考方案1】:
为什么不只运行一个异步循环?
while(someCondition)
DoTheWork();
await Task.Delay(someAmountOfTime);
如果时间很重要,您可以运行StopWatch
来测量时间的流逝并进行一些计算以找出someAmountOfTime
应该是什么。否则,只需使用一个常量值。
【讨论】:
此解决方案不保证执行之间的恒定间隔。为了使其保持不变(假设每个作业的持续时间少于延迟时间),您应该在执行作业之前创建Task.Delay
任务,然后在之后创建await
任务。
@TheodorZoulias 是的,但是 OPs 现有的解决方案使用了固定的间隔 between 作业,所以这大致相同。不过,我喜欢在工作之前设置延迟的想法。不错。
@你是对的。您的解决方案与 OP 的当前设置相匹配。我相信他们会更喜欢恒定的间隔。 :-)【参考方案2】:
您需要使用共享信号量将您的方法的并发执行次数限制为一次 1。在启动计时器之前将信号量实例化一次,并在每次执行计时器时重用它。
当方法启动时,您需要等待信号量可用。在方法结束时,您需要释放信号量。这样可以确保在等待和释放之间一次只执行一次。
使用信号量比锁定更好,因为它允许您提供超时,即放弃前等待的最长时间。
https://docs.microsoft.com/dotnet/standard/threading/semaphore-and-semaphoreslim
【讨论】:
以上是关于如何使用 System.Threading.Timer c# 在同一线程上运行代码的主要内容,如果未能解决你的问题,请参考以下文章
如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]
如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?