【问题标题】:Threading Timer Not working?线程定时器不工作?
【发布时间】:2011-10-18 00:11:27
【问题描述】:
public class DHSApi
{
    public void StartFetchingTickerInfo()
    {

        client = new clientAPI();

        Trace.Write("Timer Started" );
        Timer timer = new Timer(new TimerCallback(GetQuotes), null, 0, 10000);

    }

    public void GetQuotes(object obj)
    {
        Trace.Write("Timer Pass:" + timerPasser++);
        if (currentWork > workList.Count - 1)
            currentWork = 0;
        Thread t = new Thread(Quote);
        t.Start(workList);


    }
    private void Quote(object obj)
    {
        Trace.Write("Entered Quotes:" + quotesIn++);

        lock (workList)
        {
            List<Work> works = new List<Work>();
            int error = 0;

            foreach (Work w in works)
            {

                client.CreateClientAPI();
                //Work Work Work
                client.DestroyClientAPI();
            }
            Trace.Write("Exits Quotes:" + d);
            QuotesReturned(works);
        }

    }
    private void QuotesReturned(List<Work> works)
    {
        Model.PIP pip;
        foreach (Work w in works)
        {

        }
    }
}

计时器基本功能假设在 Web 服务中终生运行...问题是计时器工作一两次,然后停止,我不知道为什么?我找不到原因。应该是线程的原因。当我基于偶数处理程序而不是计时器实现类似的事情时,也出现了同样的问题。

Timer StartedTimer Pass:0Entered Quotes:0Exits Quotes:1线程 '' (0xb18) 已退出,代码为 0 (0x0)。 计时器通行证:1 输入行情:1 退出行情:2 线程 '' (0x153c) 已退出,代码为 0 (0x0)。 计时器通行证:2 输入行情:2 退出行情:3 线程 '' (0xf10) 已退出,代码为 0 (0x0)。 计时器通行证:3 输入行情:3 退出行情:4 线程“”(0x1044)已退出,代码为 0(0x0)。 计时器通行证:4 输入行情:4 退出行情:5 线程 '' (0xd24) 已退出,代码为 0 (0x0)。 计时器通行证:5 输入行情:5 退出行情:6 线程 '' (0x688) 已退出,代码为 0 (0x0)。 计时器通行证:6 输入行情:6 退出行情:7 线程 '' (0x17c8) 已退出,代码为 0 (0x0)。 计时器通行证:7 输入行情:7 退出行情:8 线程 '' (0xf34) 已退出,代码为 0 (0x0)。 计时器通行证:8 输入行情:8 退出行情:9 线程 '' (0x16f4) 已退出,代码为 0 (0x0)。 计时器通行证:9 输入行情:9 退出行情:10 线程 '' (0xf74) 已退出,代码为 0 (0x0)。 计时器通行证:10 输入行情:10 退出行情:11 线程 '' (0x938) 已退出,代码为 0 (0x0)。 计时器通行证:11 输入行情:11 退出行情:12 线程 '' (0x1048) 已退出,代码为 0 (0x0)。 计时器通行证:12 输入行情:12 退出行情:13 线程 '' (0x17dc) 已退出,代码为 0 (0x0)。 计时器通行证:13 输入行情:13 退出行情:14 线程 '' (0x174c) 已退出,代码为 0 (0x0)。 计时器通行证:14 输入行情:14 退出行情:15 线程 '' (0x132c) 已退出,代码为 0 (0x0)。 计时器通行证:15 输入行情:15 退出行情:16 线程 '' (0x3f8) 已退出,代码为 0 (0x0)。 计时器通行证:16 输入行情:16 退出行情:17 线程 '' (0x10cc) 已退出,代码为 0 (0x0)。 计时器通过:17线程“”(0x1534)已退出,代码为0(0x0)。 输入报价:17退出报价:18线程“”(0x1050)已退出,代码为0(0x0)。 线程 '' (0x850) 以代码 0 (0x0) 退出。 计时器通行证:18 输入行情:18 退出行情:19 线程 '' (0xca0) 已退出,代码为 0 (0x0)。 计时器通行证:19 输入行情:19 退出行情:20 线程 '' (0x1120) 已退出,代码为 0 (0x0)。 计时器通行证:20 输入行情:20 退出行情:21 线程 '' (0x508) 已退出,代码为 0 (0x0)。 计时器通行证:21 输入行情:21 退出行情:22 线程 '' (0x1598) 已退出,代码为 0 (0x0)。 计时器通行证:22 输入行情:22 退出行情:23 线程 '' (0xb2c) 已退出,代码为 0 (0x0)。 计时器通行证:23 输入行情:23 退出行情:24 线程 '' (0x1600) 已退出,代码为 0 (0x0)。 计时器通行证:24 输入行情:24 退出行情:25 线程 '' (0x13bc) 已退出,代码为 0 (0x0)。 计时器通行证:25 输入行情:25 退出行情:26 线程 '' (0x131c) 已退出,代码为 0 (0x0)。 计时器通行证:26 输入行情:26 退出行情:27 线程 '' (0x5f4) 已退出,代码为 0 (0x0)。 计时器通行证:27 输入行情:27 退出行情:28 线程 '' (0x128) 已退出,代码为 0 (0x0)。 计时器通行证:28 输入行情:28 退出行情:29 线程 '' (0x1420) 已退出,代码为 0 (0x0)。 计时器通过:29线程“”(0xc64)已退出,代码为0(0x0)。 输入行情:29 退出行情:30 线程 '' (0xedc) 已退出,代码为 0 (0x0)。 计时器通行证:30 输入行情:30 退出行情:31 线程“”(0x136c)已退出,代码为 0(0x0)。 计时器通行证:31 输入行情:31 退出行情:32 线程 '' (0xeb8) 已退出,代码为 0 (0x0)。 计时器通行证:32 输入行情:32 退出行情:33 线程 '' (0x690) 已退出,代码为 0 (0x0)。 计时器通行证:33 输入行情:33 退出行情:34 线程 '' (0x1320) 已退出,代码为 0 (0x0)。 计时器通行证:34 输入行情:34 退出行情:35 线程 '' (0x11b8) 已退出,代码为 0 (0x0)。 计时器通行证:35 输入行情:35 退出行情:36 线程 '' (0x1684) 已退出,代码为 0 (0x0)。 计时器通行证:36 输入行情:36 退出行情:37 线程 '' (0x1294) 已退出,代码为 0 (0x0)。 线程 '' (0x1240) 以代码 0 (0x0) 退出。 线程 '' (0xde8) 已退出,代码为 0 (0x0)。

然后是停止....

完成了……不好

解决办法 放行Timer timer;在类的顶部

【问题讨论】:

  • 如果你在那些空的 catch 块中加入一些日志记录,你可能会学到一些东西。
  • 没问题!它只被调用一次!我检查好了!
  • y 这个问题是负面评价吗?
  • -1 表示没有将其归结为相关代码。我们不必查看所有这些属性。
  • 有点...我仍然注意到很多松散的结局,例如currentWork1

标签: c# multithreading timer


【解决方案1】:

定时器实例是在ctor中声明的,那么它将在相对较短的时间内被垃圾。因而定时器的死亡。在类级别固定“计时器”变量。

但是,一旦您不再使用计时器,您应该将其丢弃。

干杯

【讨论】:

  • 不是问题吗?问题发生了一些变化。不过还是谢谢
  • 问题是你解释的计时器消失了......你有解决办法吗?为此?
  • 您好,只需将静态成员变量添加到包含 Timer 的类中。对于VB,这个woule是这样的:“Private Shared _MyTimer As Threading.Timer = Nothing”,然后在设置定时器回调的方法中:“Dim TimerDelegate As Threading.TimerCallback = AddressOf Settings.RunScheduledTasks”和“_MyTimer = New Threading.Timer (TimerDelegate, Nothing, New TimeSpan(0, 1, 0), New TimeSpan(0, 10, 0))"
【解决方案2】:
  Timer timer = new Timer(new TimerCallback(GetQuotes), null, 0, 10000);
  timer.InitializeLifetimeService();

InitializeLifetimeService() 返回一个你应该做某事的对象。默认租约使用 10 秒的超时,与您的时间间隔相同。如果处理时间太长,您的计时器被取消似乎是合理的。

【讨论】:

  • 10 分钟,而不是几秒钟。这是一个垃圾电话,这不是一个远程处理方案。
【解决方案3】:

您说这是一个 Web 服务 - 不能保证计时器在 Web 服务中正常工作,因为不能保证拥有线程的生命周期。考虑使用在应用域启动时创建的全局工作线程。

一个基本的全局工作线程是:

static bool _stopPolling = false;
static Thread _pollerThread;
static object _oneTimeLocker = new object();

private static CreatePollerThread()
{
  if(_pollerThread == null)
  {
    lock(_oneTimeLocker)
    {
      if(_pollerThread == null) //double-check
      {
        _pollerThread = new Thread(
        new ThreadStart(() => 
        { 
          while(true && !_stopPolling)
          { 
            DoWork(); 
            Thread.Sleep(10000); 
          }
        }));  
        _pollerThread.Start();
      }
    }
  }
}

我在那里使用了双重检查锁,以防您想要启动全局线程以响应请求(不是最佳策略 - 因为您可以有多个请求尝试初始化线程,可能会执行多个次)。这不是唯一的方法 - 但考虑到我在工作并且没有太多时间,这让我现在无法接受!

这里的一个重要因素是您用来以友好方式关闭线程的 _stopPolling 布尔值。

如果您在 Asp.Net 中 - 那么这个 SO:Application_End and background processes, exiting ASP.Net application gracefully 以及 Aristos 的回答将帮助您了解如何最好地关闭线程。

【讨论】:

  • 这有点像它启动一次并假设完成它的工作......什么是全局工作线程你能告诉我怎么做吗?
  • @Taufiq - 为您添加示例
  • 谢谢,但你能告诉我这对我有什么帮助以及如何在我的代码上实现它给出了一个跟踪日志..计时器刚刚停止......
猜你喜欢
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-25
  • 2019-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多