0

I want to create a new countdown timer every time an if statement is true, it should work like this:

Eg:

List<int> intList = new List<int>();



foreach(a in b)
{
   if(a==1)
   {
     intList.Add(a.somevalue)
     //should create a new countdown timer for 1 hour and once the time is finished, it
     should remove the added value from the list
   }
}

How do i achieve this ??

Thanks.

Shiva
  • 20,575
  • 14
  • 82
  • 112
vmark99
  • 147
  • 9

3 Answers3

5

Well, first off, we really shouldn't be modifying a List from different threads, so this puts us in the position of either ensuring that all of the timed events go through a single thread, or apply their own synchronization of some kind, or that we instead use a different data structure that has no problem being used from multiple threads.

As for actually doing something in an hour, while you could use a Timer, Task.Delay fits very nicely here:

List<int> list = new List<int>();
object key = new object();

foreach (int a in b)
    if (a == 1)
    {
        var value = GetValue(a);
        list.Add(value);
        Task.Delay(TimeSpan.FromHours(1))
            .ContinueWith(t => { lock (key)list.Remove(value); });
    }
Servy
  • 202,030
  • 26
  • 332
  • 449
  • OP didn't mention how the "list" is used but one of those lock-free data structures could be used to remove the lock contention. – treehouse Dec 23 '13 at 20:47
  • @KaiWang Yes, it's certainly possible, which is why I mention it, but the only one that has a fundamental concept of "remove this item" instead of "give me the next item you have" is `ConcurrentDictionary`, and it seems a bit hackish to try and use that here. It's worth considering though for sure. – Servy Dec 23 '13 at 20:49
  • If i use this method will the loop still continue ? or will it wait till the 1 hour ends ? – vmark99 Dec 23 '13 at 20:59
  • @vmark99 This code will not take an hour to execute, no. Instead it will iterate through the collection as fast as it can and schedule some number of operations to take place in an hour. – Servy Dec 23 '13 at 21:02
0

There are many links that can help you :)

Is there a way to have a countdown timer while waiting for input?

then you could creat a concurrentbag which could hold references to your timers.

Community
  • 1
  • 1
Softwarehuset
  • 815
  • 4
  • 10
-3

Simplest answer:

var value = a.someValue;
new Thread(() => { Thread.Sleep(60 * 60 * 1000); intList.Remove(value); }).Start();

But realistically you're going to want to save off the thread reference so you can interrupt it later if needed. In particular your program won't exit if there are background threads running.

TypeIA
  • 16,916
  • 1
  • 38
  • 52
  • Creating tons and tons of hard threads just to have them sit around for an **hour** doing nothing productive at all is a horrible waste of system resources. – Servy Dec 23 '13 at 20:24
  • @Servy They aren't really wasting any resources if they're asleep. There isn't much overhead on threads nowadays. Absolutely agree though, this is not a good solution if there are going to be a very large number of them. – TypeIA Dec 23 '13 at 20:26
  • They aren't wasting *as much* if they're asleep, but they're still consuming resources. This doesn't scale well at all. – Servy Dec 23 '13 at 20:27
  • Default Stack Size is 1 MB/Thread. As @Servy said, this solution doesn't scale. – treehouse Dec 23 '13 at 20:45