0

I currently have a static List of custom objects (but I've tested with a List of int as well). I'm modifying this List in 2 methods:

  1. Button_Click event
  2. System.Timers.Timer that elapses every 5 minutes

The problem is that it seems like List is initialized for both methods when the application begins and is independent. Meaning when I add an element to #1, it is not reflected in #2. I'm guessing it's because the Timers.Timer is started on a separate thread?

In which case, I have tried putting a primitive int as well. In that case, the number is changed in both and reflects one another. Is the problem due to the fact that it is a dynamic list of objects?

What would you recommend I do?

Thank you!

Sorry for not posting the code earlier! I tried with the lock recommendation, to no avail. I've never used it before so please let me know if I didn't use it correctly.

    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` is not thread-safe. – SLaks Sep 21 '14 at 14:00
  • 2
    While `List` is _not_ threadsafe, what you're describing doesn't seem to be the issue. Can you post the relevant code and a simple code example that we can reproduce the issue? EDIT: Ahh, but it works for `int`? Yeah, simply could be threading issues. Try applying a `lock` around any code that modifies or accesses the list. – Chris Sinclair Sep 21 '14 at 14:00
  • 1
    Impossible to say without code but I doubt thread safety is the issue with updates every 5 minutes. Chances of a racing condition are pretty slim and I guess you can reproduce it every time. – Stilgar Sep 21 '14 at 14:04
  • Sorry guys! I posted the code in my first post, I also tried with lock (put in comment) but it didn't seem to work. It's the first time I use lock though, so please let me know if that's not how you implement it. – Dave Sparky Sep 21 '14 at 14:20
  • What platform is this running in? ASP.NET? WPF? Console application? EDIT: And judging from your output, it looks like it's behaving the same way for the `List` as it does for your `List` despite what you said that `List` works fine and the change is reflected in both threads? – Chris Sinclair Sep 21 '14 at 14:21
  • It's a Console application. Edit: No, sorry for being unclear. List and List both don't work. However, int would work. – Dave Sparky Sep 21 '14 at 14:23
  • What happens if you trigger your `OnMessage` not so close to the 5 minute mark? Maybe try at 4 minutes? – Chris Sinclair Sep 21 '14 at 14:26
  • 1
    This is most typically a copy/paste accident. You re-organized your code and ended up with *two* variables named listInt in different source files. Easy to diagnose with the editor's "Go To Definition" context menu item. – Hans Passant Sep 21 '14 at 14:29

1 Answers1

0

My bad guys, this was my mistake all along..

It was not a copy-paste mistake. However, it seems like I confused my test cases and the problem occured when I was trying to Remove an item from the lists, not Add it. I had a similar issue with a another non-static variable so obviously, when this problem occured with a static variable, I thought that the Timer was the problem.

The item wasn't Removed correctly due to the fact that I was trying to remove a copied element, not the element in itself: "List.Remove" in C# does not remove item?

Thanks for all your help and sorry for the confusion!

Community
  • 1
  • 1