- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在有人对我发火之前,我会说,在这种情况下,考虑到在我的代码中广泛使用这个对象,我有一个单例是有意义的,如果有人有比 DI 更好的方法,我会很想听,但我希望这不是这篇文章的重点,更多的是帮助解决它。
话虽这么说,但问题是:似乎在给定的时间后,我失去了对我的类(class)调度程序的引用,并且内部有一个不再触发的计时器滴答声。这是因为它以单例方式使用并且一旦失去引用就会被 GC 处理吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace MessageQueueInterface
{
public class Scheduler
{
private const int _interval = 1000;
private readonly Dictionary<DateTime, Action> _scheduledTasks = new Dictionary<DateTime, Action>();
private readonly Timer _mainTimer;
public Scheduler()
{
_mainTimer = new Timer();
_mainTimer.Interval = _interval;
_mainTimer.Tick += MainTimer_Tick;
_mainTimer.Start();
}
void MainTimer_Tick(object sender, EventArgs e)
{
CheckStatus();
}
public void Add(DateTime timeToFire, Action action)
{
lock (_scheduledTasks)
{
if (!_scheduledTasks.Keys.Contains(timeToFire))
{
_scheduledTasks.Add(timeToFire, action);
}
}
}
public void CheckStatus()
{
Dictionary<DateTime, Action> scheduledTasksToRemove = new Dictionary<DateTime, Action>();
lock (_scheduledTasks)
{
foreach (KeyValuePair<DateTime, Action> scheduledTask in _scheduledTasks)
{
if (DateTime.Now >= scheduledTask.Key)
{
scheduledTask.Value.Invoke();
scheduledTasksToRemove.Add(scheduledTask.Key, scheduledTask.Value);
}
}
}
foreach (KeyValuePair<DateTime, Action> pair in scheduledTasksToRemove)
{
_scheduledTasks.Remove(pair.Key);
}
}
}
}
在其他类中是通过以下方式访问的
ApplicationContext.Current.Scheduler.Add(DateTime.Now.AddSeconds(1), ResetBackColor);
ApplicationContext
是我的单例
我也知道 datetime 对象不是字典的最佳 KEY,但它适合我的目的
这是单例
public class ApplicationContext
{
private static ApplicationContext _context;
private Scheduler _scheduler;
public Scheduler Scheduler
{
get { return _scheduler; }
}
private void SetProperties()
{
_scheduler = new Scheduler();
}
public static ApplicationContext Current
{
get
{
if (_context == null)
{
_context = new ApplicationContext();
_context.SetProperties();
}
return _context;
}
}
}
最佳答案
您发布的类似乎不是您的单例类。该代码会更有帮助。
无论如何,是的,如果计时器超出范围并被 GC 处理,那么它将停止触发事件。更有可能的是调度程序立即超出范围,并且在发生这种情况和 GC 发生之间只是有一个延迟。
发布您的单例代码可以让我或其他任何人给出更具体的答案。
编辑
考虑到单例类的简单性,我突然想到的唯一潜在问题是 Current
属性的竞争条件。假设您没有锁定任何东西,那么当 Current
属性为 null 时,两个线程同时访问该属性可能会以不同的引用结束,而最后一个被设置的将是唯一一个有一个引用,其范围将超出属性 getter 本身的范围。
我建议创建一个简单的同步 object
实例作为静态成员,然后将其锁定在 getter 中。这应该可以防止出现这种情况。
顺便说一句,SetProperties()
方法的目的是什么,而不是在无参数构造函数中甚至在声明点初始化变量?拥有这样的功能允许创建一个新的 Scheduler
对象并放弃现有的对象。
关于c# - 线程和单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/976749/
我最近购买了《C 编程语言》并尝试了 Ex 1-8这是代码 #include #include #include /* * */ int main() { int nl,nt,nb;
早上好!我有一个变量“var”,可能为 0。我检查该变量是否为空,如果不是,我将该变量保存在 php session 中,然后调用另一个页面。在这个新页面中,我检查我创建的 session 是否为空,
我正在努力完成 Learn Python the Hard Way ex.25,但我无法理解某些事情。这是脚本: def break_words(stuff): """this functio
我是一名优秀的程序员,十分优秀!