服务计时器永远保持活动状态
本文关键字:活动状态 永远 计时器 服务 | 更新日期: 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
不会在调用后保留对象,只会在调用之前保留对象。
若要防止收集对象,需要保留对它的引用。这可以简单地通过将其存储在类的字段中来实现(只要类实例本身不超出范围)。