如何使用 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.DelaySemaphoreSlimWaitAsync 方法以初始计数= 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 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?

WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?