C# 服务计时器永远有效

C# 服务计时器永远有效,c#,garbage-collection,C#,Garbage Collection,我正在用c#构建一个服务应用程序。我正在尝试每隔2秒使用计时器执行一次操作(数组)。但是我的计时器在我的函数调用完成后一直死机 我的Onstart: ... Alaram Fi = new Alaram(); Fi.AgentStart(); GC.KeepAlive(Fi); ... 我的阿拉姆班: public void AgentStart() { ... int i = 0; Timer[]

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

我的Onstart:

   ...
   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
方法中的数组)上进行主动垃圾收集。一旦数组和计时器超出范围(当方法执行完毕时),它们将开始被垃圾收集


您将需要在数组将保留在作用域中的位置声明该数组。一种方法是将数组标记为静态并将其放置在类级别。接下来,在类的静态构造函数中实例化分配给数组的计时器。这将使它们保持活动状态。

GC.KeepAlive
只会阻止计时器在声明(或存储)它们的作用域(即
AgentStart
方法中的数组)上进行主动垃圾收集。一旦数组和计时器超出范围(当方法执行完毕时),它们将开始被垃圾收集


您将需要在数组将保留在作用域中的位置声明该数组。一种方法是将数组标记为静态并将其放置在类级别。接下来,在类的静态构造函数中实例化分配给数组的计时器。这将使它们保持活动状态。

根据
KeepAlive
的文档:

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

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

换句话说,
KeepAlive
什么也不做,只是引用变量,这样GC就不会在调用
KeepAlive
之前收集它。这对于需要保留直到超出范围的局部变量非常有用。下面是一个简单的例子:

void DoSomething()
{
    Timer myTimer = ...;
    // long-running operation
    GC.KeepAlive(myTimer);
}
如果没有
KeepAlive
,该方法可以优化到在长时间运行操作的中途收集计时器的程度

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


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

根据
KeepAlive
的文档:

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

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

换句话说,
KeepAlive
什么也不做,只是引用变量,这样GC就不会在调用
KeepAlive
之前收集它。这对于需要保留直到超出范围的局部变量非常有用。下面是一个简单的例子:

void DoSomething()
{
    Timer myTimer = ...;
    // long-running operation
    GC.KeepAlive(myTimer);
}
如果没有
KeepAlive
,该方法可以优化到在长时间运行操作的中途收集计时器的程度

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


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

您有没有建议让它永远存在??我也让我的班级保持活力,这足够吗?你有没有建议让它永远活下去??我也让我的班级保持活力,够了吗?