2017-04-26 8 views
-3

このwhileループをより効率的なイベント駆動型コードなどで置き換える方法を探しています。このC#の例でwhile(true)を避ける方法

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

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

ユニットは他のスレッドで削除することができ、スレッドセーフであるconcurrentDictionaryにあります。

このコードの実装を改善していただきありがとうございます。

はありがとう

+0

いつでも実行したい場合は、While(true)の何が問題なのですか?それ以外の場合は、コンソールを開いている場合、ボタンを押したときに閉じることができます。 – coinbird

+0

これは、このようにCPU時間を大量に消費しています。 unit.countが何とか10以下に落ちると、この作品を実行する方法を探しています! –

+0

それが10以下で、それがCPUを使用しているかどうかをチェックする必要があります。おそらく頻繁にチェックしないでください。 – coinbird

答えて

1

ここでは、イベントを使用して作成した例を示しますが、明らかに完全ではありませんが、必要なものを追加して希望の状態にすることができます。

キーが削除されると辞書のカウントがチェックされ、カウントが指定された数よりも小さい場合はイベントが発生します。

注:これはスレッドセーフであるかどうかはわかりませんが、私はスレッドで作業することに慣れていないので、ConcurrentDictionaryがそれを処理してくれることを願っています。

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; 
     } 
    } 
} 
1
もメインスレッドで閉塞を取り除くことながら、あなたは whilethread.sleepを取り除くためにタイマーを使用することができます

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; 
} 

の作業例:fiddle

Timer Documentation

Related Answer

関連する問題