【发布时间】:2014-09-21 13:56:33
【问题描述】:
我目前有一个自定义对象的静态列表(但我也使用 int 列表进行了测试)。我正在用 2 种方法修改此列表:
- Button_Click 事件
- System.Timers.Timer 每 5 分钟运行一次
问题在于,当应用程序开始并且独立时,这两种方法的 List 似乎都被初始化了。这意味着当我向#1 添加一个元素时,它不会反映在#2 中。我猜是因为 Timers.Timer 是在单独的线程上启动的?
在这种情况下,我也尝试过放置一个原始 int。在这种情况下,两者的数字都会发生变化并相互反映。问题是因为它是一个动态的对象列表吗?
你会推荐我做什么?
谢谢!
很抱歉没有早点发布代码!我尝试了锁定建议,但无济于事。我以前从未使用过它,所以如果我没有正确使用它,请告诉我。
protected System.Timers.Timer fiveMinutesTimer
public static List<int> listInt = new List<int>();
public static int counter = 0;
public override void OnLoginCompleted()
{
fiveMinutesTimer = new System.Timers.Timer();
fiveMinutesTimer.Interval = 300000;
fiveMinutesTimer.Elapsed += (sender, e) => OnFiveMinutesTimerElapsed(sender, e, EChatEntryType.ChatMsg);
fiveMinutesTimer.Enabled = true;
}
public override void OnMessage(string message, EChatEntryType type)
{
//lock (listInt)
//{
listInt.Add(3);
listInt.Add(3);
listInt.Add(3);
counter += 3;
Console.WriteLine("OnMessage: " + listInt.Count);
Console.WriteLine("OnMessage int: " + counter);
//}
}
private void OnFiveMinutesTimerElapsed(object source, System.Timers.ElapsedEventArgs e, EChatEntryType type)
{
//lock (listInt)
//{
listInt.Add(3);
counter++;
Console.WriteLine("Timer: " + listInt.Count);
Console.WriteLine("Timer int: " + counter);
//}
}
Triggering OnMessage at 4:59
OnMessage: 3
OnMessage int: 3
OnFiveMinutesTimerElapsed
Timer: 1
Timer int: 4
Triggering OnMessage at 9:59
OnMessage: 6
OnMessage int: 7
OnFiveMinutesTimerElapsed
Timer: 2
Timer int: 8
【问题讨论】:
-
List<T>不是线程安全的。 -
虽然
List<T>不是 线程安全的,但您所描述的似乎不是问题所在。您能否发布相关代码和我们可以重现该问题的简单代码示例?编辑:啊,但它适用于int?是的,可能只是线程问题。尝试在任何修改或访问列表的代码周围应用lock。 -
不可能说没有代码,但我怀疑线程安全是每 5 分钟更新一次的问题。比赛条件的机会非常渺茫,我想您每次都可以重现它。
-
对不起各位!我在我的第一篇文章中发布了代码,我也尝试了锁定(发表评论),但它似乎没有用。这是我第一次使用锁,所以如果你不是这样实现的,请告诉我。
-
这是最典型的复制/粘贴事故。您重新组织了代码,最终在不同的源文件中使用了名为 listInt 的 两个 变量。使用编辑器的“转到定义”上下文菜单项轻松诊断。