-3

I am looking for a way to replace this while loop with something more efficient e.g event driven code.

While(true)\\ must constantly monitor units
{ 
  if(units.count< 10)
  {    
    \\ launch units    
  }

  thread.sleep(100); \\ to avoid 100% CPU usage
}

Units can be deleted in other threads and they are in concurrentDictionary which is thread safe.

I would appreciate your suggestions for better implementation of this code.

Thank you

  • If you want it to always run, what's wrong with While(true)? Otherwise if you have a console open you could have it close when you press a button. – coinbird Apr 26 '17 at 18:26
  • It's consumming a lot of CPU time in this way. I am looking for a way to run this piece whenever units.count falls below 10 somehow ! – sarah daneshvar Apr 26 '17 at 18:31
  • You have to check if it's below 10, and that uses CPU. Maybe check less often? – coinbird Apr 26 '17 at 18:35
  • 3
    You could create an event that's triggered or just simply call a method that does the check when any bit of code updates `units`. If you control all of the code that can alter `units`, then you don't need to poll for changes like you're doing. – itsme86 Apr 26 '17 at 18:38
  • You can do this in event way, in timer way, in schedule way, in cancelling waiting way, in `async` way, etc. too broad to answer, imho – VMAtm Apr 26 '17 at 22:04

2 Answers2

1

You can use timers to get rid of the the while and the thread.sleep while also getting rid of the blockage on the main thread:

private static void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
{
    if(unitsCount < 10)
    {    
        //launch Units
    }
 }

public static void Main (string[] args) 
{
    System.Timers.Timer aTimer = new System.Timers.Timer();
    aTimer.Elapsed+=new System.Timers.ElapsedEventHandler(OnTimedEvent);

    aTimer.Interval=100;
    aTimer.Enabled=true;
}

Working example: fiddle

Timer Documentation

Related Answer

Community
  • 1
  • 1
wotanii
  • 2,470
  • 20
  • 38
1

Here is an example I created using an Event, it's obviously not complete, but you should be able to add what you need to it to get it how you want it.

It checks the count of the dictionary when a key is removed from it and then fires the event if the count is less than the number specified.

Note: I have no idea if this is thread safe, I'm not familiar with working with threads, I hope ConcurrentDictionary is taking care of that.

public static partial class Program 
{
    static void Main(string[] args)
    {
        DictionaryCount<int, string> dict = new DictionaryCount<int, string>();
        dict.CountLessThan += dict_TryRemove;
        dict.CountToFireOn = 1;
        dict.TryAdd(1, "hello");
        dict.TryAdd(2, "world");
        dict.TryAdd(3, "!");
        string outValue;
        dict.TryRemove(2, out outValue);
        dict.TryRemove(1, out outValue);
        Console.ReadKey(true);
    }

    private static void dict_TryRemove(object sender, CountEventArgs e)
    {
        DictionaryCount<int, string> dict = sender as DictionaryCount<int, string>;
        Console.WriteLine(dict.Count);
        Console.WriteLine("Count less than 2!");
    }

    public class DictionaryCount<TKey, TValue> : ConcurrentDictionary<TKey, TValue>
    {
        public int CountToFireOn { get; set; }

        public DictionaryCount() : base() { }

        public delegate void CountEventHandler(object sender, CountEventArgs e);
        public event CountEventHandler CountLessThan;

        public new bool TryRemove(TKey key, out TValue value)
        {
            bool retVal = base.TryRemove(key, out value);
            if (this.Count <= CountToFireOn)
            {
                CountEventArgs args = new CountEventArgs(this.Count);
                CountLessThan(this, args);
            }
            return retVal;
        }
    }

    public class CountEventArgs
    {
        public int Count { get; set; }

        public CountEventArgs(int count)
        {
            this.Count = count;
        }
    }
}
Blake Thingstad
  • 1,639
  • 2
  • 12
  • 19