C#计时器出现问题

3

我有一个方法,想要每3秒钟在单独的线程中调用一个方法(称为myFanc)。

下面的代码可以轻松实现这个功能:

 Timer myTimer = new Timer();
 myTimer.Elapsed += new ElapsedEventHandler( myFanc );
 myTimer.Interval = 3000;
 myTimer.Start();

以上代码可能会导致在另一个对myFanc的调用还没有完成时就调用myFanc。

我的问题是,我希望在再次调用她之前也能让myFanc完成,因此基本上我想在每3秒钟后在单独的线程中调用该方法,如何做到呢?

如果解决方案不使用Timer类,我也不介意,我只想让这个行为起作用。

6个回答

6

将定时器的AutoReset属性设置为false,然后在事件处理程序(即"myFanc")的末尾再次调用定时器的Start方法。


2
在 myFunc 的顶部放置以下内容:
myTimer.Enabled = false;

最后,在完成时放置这个

myTimer.Enabled = true;

在函数执行期间,这将导致您暂时禁用计时器。


1
不要使用计时器,在线程中循环调用“myfanc”,并使用。
Thread.Sleep(3000);

插入所需的延迟。


@Delashmate:如果您确实已经在使用不同的线程,则我支持这个建议-让第二个线程休眠是处理延迟的首选方法。 - Jim Brissom
@Delashmate:根据什么推理?这是使用thread.sleep的适当方式。 - Kurru
@Jim,Thread.Sleep会消耗CPU吗?如果是的话,那么它不是优雅的解决方案。 - Delashmate
1
Thread.Sleep会暂停线程,因此它不会消耗CPU。 - Felice Pollano
@Felice,据我所知,操作系统在Thread.Sleep中没有使用事件,它只是不断地检查“我能继续吗?我能继续吗?”等待时间过去。 - Delashmate
1
@Delashmate事件与Thread.Sleep无关。您可以通过暂停线程,例如十秒钟(10000),来检查您的进程的CPU消耗为0... - Felice Pollano

1

这是我使用的解决方案 - 感谢Jim

using System;
using System.Timers;
using System.Threading;

class myApp
{
    public static void Main()
{
      System.Timers.Timer myTimer = new System.Timers.Timer();
      myTimer.Elapsed += new ElapsedEventHandler( myFanc );
      myTimer.Interval = 1000;
      myTimer.AutoReset = false;
      myTimer.Start();

      while ( Console.Read() != 'q' )
      {
          ;    // do nothing...
      }
    }

public static void myFanc(object source, ElapsedEventArgs e)
{
    Console.Write("\r{0}", DateTime.Now);

    Thread.Sleep(3000); //the sleep here is just to test the method, wait to be finished before another call the myFanc method is being performed
    System.Timers.Timer myTimer = new System.Timers.Timer();
    myTimer.Elapsed += new ElapsedEventHandler(myFanc);
    myTimer.Interval = 1000;
    myTimer.AutoReset = false;
    myTimer.Start();

}

}


0
使用线程和Thread.Sleep(x)来实现,如下所示:
Thread thread = new Thread(new ThreadStart(myTimer));
thread.Start();


void myTimer()
{
    while (!exit)
    {
        myFunc();
        Thread.Sleep(3000);
    }
}

为什么?它非常适合像这里所需的引入延迟。 - Kurru

0

我现在能想到的有两种方法:

  1. 在myFanc方法内部停止和启动计时器,这样可以确保每次运行之间间隔3秒。
  2. 将你的代码包装在一个锁定的myFanc内部,如果它没有完成,它将跳过一个回合。

确保使用正确的计时器...system.threading.timer是一个单独的线程。Windows.forms中的计时器类(或类似的类)不是。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接