服务计时器永远保持活动状态

本文关键字:活动状态 永远 计时器 服务 | 更新日期: 2023-09-27 18:32:26

我用 C# 构建一个服务应用程序。 我正在尝试每 2 秒使用计时器进行一次操作(数组)。 但是我的计时器在我的函数调用完成后保持死亡。

我的开始:

   ...
   Alaram  Fi = new Alaram();
   Fi.AgentStart();
   GC.KeepAlive(Fi);
   ...

我的阿拉拉姆班:

    public void AgentStart()
    {
        ...
        int i = 0;
        Timer[] timers = new Timer[count];
        while (myReader.Read())
        {
            timers[i] = new Timer(coba, myReader["DeviceId"], 0, 2000);
            i++;
        }
        GC.KeepAlive(timers);
     }

我的操作:

 public void coba(object id)
 {
        ...
        int sec = Convert.ToInt32((string)myCommand.ExecuteScalar());
        sec++;
        myCommand = new SqlCommand("UPDATE Roles  SET  Value ='" + sec.ToString() + "' WHERE   Name = 'Fire" + id.ToString() + "'", ibmsConnect);
        myCommand.ExecuteNonQuery();
        ...
  }
我的计时器

最多只能执行 36 次,之后我的计时器不再执行。我需要它保持活动状态,直到服务停止

有人知道为什么我的计时器总是停止滴答作响吗?

服务计时器永远保持活动状态

>GC.KeepAlive只会阻止在声明(或存储)它们的范围的计时器上进行积极的垃圾回收,这将是 AgentStart 方法中的数组。一旦数组和计时器超出范围(当方法完成执行时),它们将开始被垃圾回收收集。

您需要在数组将保留在范围内的位置声明数组。一种方法是将数组标记为静态并将其放置在类级别。接下来,在类的静态构造函数中实例化分配给数组的计时器。这应该让他们活着。

根据KeepAlive的文档:

此方法引用 obj 参数,使该对象不符合从例程开始到调用此方法的点(按执行顺序)进行垃圾回收的条件。在 obj 必须可用的指令范围的末尾(而不是开头)对此方法进行编码。

KeepAlive 方法不执行任何操作,除了延长作为参数传入的对象的生存期外,不会产生任何副作用。

换句话说,KeepAlive 什么都不做,而是引用变量,因此 GC 不会在KeepAlive调用之前收集它。这对于需要保留直到超出范围的局部变量很有用。下面是一个简单的示例:

void DoSomething()
{
    Timer myTimer = ...;
    // long-running operation
    GC.KeepAlive(myTimer);
}

如果没有KeepAlive,该方法可以优化到在长时间运行的操作中途收集计时器的程度。

简单地说,KeepAlive不会在调用后保留对象,只会在调用之前保留对象。

若要防止收集对象,需要保留对它的引用。这可以简单地通过将其存储在类的字段中来实现(只要类实例本身不超出范围)。