c# - 计时器范围和正确处置
问题描述
所以我正在开发一个使用 System.Timers.Timer 对象在任务之间等待的任务调度程序。为了使用这个计时器,我将它放入实例化的静态(扩展)方法中并仅在那里使用它。我的问题是它会在该静态方法结束时得到妥善处理,还是我需要做更多的事情?这就是我正在使用的。
public static void Use<T>(this T o, Action<object> work) => work(o);
private void RunLoop()
{
while (!Stop)
{
try
{
//Method 1
new System.Timers.Timer((task.NextRun - DateTime.Now).TotalMilliseconds).Use(timer => {
timer.Elapsed += (s, e) => {
new Thread(new ThreadStart(RunProc)) {
Name = task.Title,
IsBackground = true
}.Start();
};
timer.AutoReset = false;
timer.Start();
});
//Method 2
using (var timer = new System.Timers.Timer((task.NextRun - DateTime.Now).TotalMilliseconds))
{
timer.Elapsed += (s, e) =>
{
new Thread(new ThreadStart(RunProc))
{
Name = task.Title,
IsBackground = true
}.Start();
};
timer.AutoReset = false;
timer.Start();
}
} catch(SqlException ex)
{ //Omitted for size }
catch (Exception ex)
{ //Omitted for size }
}
}
方法 1 会正确处理我的计时器,还是我必须调用 dispose 或处理 GC 的 using 语句才能得到它?从我一直在阅读的大多数对象来看,当它们超出使用中的 lambda 调用范围时,它们将被 GC 处理。但显然 Timers 的不同之处在于它们连接到一些非托管资源,这可能导致它们持续存在,即使您期望它们会被清理,例如超出范围。
解决方案
为了结束,我最终为每个动作创建了一个计时器列表,然后只更新间隔,并根据需要回收它们。然后添加了一个特定的功能,以在停止服务时正确停止和处理所有这些。一旦同时安排了 2 个任务,我上面的设置就会失败,因此无论哪种方式都行不通。使用这种新方法,我不必担心,因为它们要么被无限期回收,要么被专门处理掉。
推荐阅读
- mysql - MySQL innoDB 数据量大时速度非常慢 - 使用索引
- reactjs - 是否可以在 antd image.preview 组内插入视频
- plotly - 您如何根据 Plotly 上的标题将色阶居中?
- gnome - libsecret 中的 gnome_keyring_unlock_sync 等效项,用于解锁 gnome 密钥环?
- mongodb - MongoDB C 驱动程序在安装时给出关于 OpenSSL 的奇怪错误
- python-3.x - 如何使用 xlsxwriter 在格式方法中使用字符串值
- python - itertools.groupby 的反面?
- python - 如何比较数据框行的特定条件?
- javascript - 我们可以在 Shopify 上添加 CSS 类吗?
- python - Pandas 根据条件更快地移动多行