2016-09-08 9 views
0

私のC#コードに何が間違っているかを理解できません。同じイベントを発生させる複数のクラスインスタンス

System.Collections.Concurrent名前空間でConcurrentQueueクラスを使用する方法を学習しようとしています。

これを行うために、別のスレッドで同じクラスの2つのインスタンスを作成し、異なるリストボックスコントロールをコンストラクタに渡します。

EventGeneratorの各クラスインスタンスがランダムな間隔でイベントを発生させ、リストボックスをランダムに生成された番号で更新し、その番号をコンストラクタに渡されるConcurrentQueueに追加することを期待しています。

私の主なスレッドでは、両方の生成されたスレッドによってEnQueuedオブジェクトのConcurrentQueueをDeQueueする方法です。

しかし、私は、同じデータを表示する2つのEnQueueリストボックスとDeQueueリストボックスの両方がdeQueuedを持つように見えるようになっています。

それはより良い私が何をしようとしている視覚化に役立つかもしれない場合には、私のフォームの画像へのリンクと一緒に、私の説明が十分ではない、と私のコードは次の場合、私は謝罪...

フォーム

public partial class Form1 : Form 
{ 
    ConcurrentQueue<int> CQ; 
    EventGenerator eventGenerator1; 
    EventGenerator eventGenerator2; 
    public Form1() 
    { 
     InitializeComponent(); 
     CQ = new ConcurrentQueue<int>(); 
     eventGenerator1 = new EventGenerator(CQ, listBox1); 
     eventGenerator1.OnRandomEvent += new EventGenerator.RandomEventHandler(RandomEvent); 
     eventGenerator2 = new EventGenerator(CQ, listBox2); 
     eventGenerator2.OnRandomEvent += new EventGenerator.RandomEventHandler(RandomEvent); 
    } 

    private void RandomEvent(object sender, IncomingConnectionEventArgs e) 
    { 
     string s = e.Property_Int.ToString() 
      + " " 
      + e.Property_String; 
     UpdateListbox(s, e.LB); 
    } 

    private void UpdateListbox(string argstring, ListBox argListBox) 
    { 
     if (InvokeRequired) 
     { 
      Invoke(new Action<string, ListBox>(UpdateListbox), new object[] { argstring, argListBox }); 
      return; 
     } 
     int n; 
     bool b = false; 
     //do 
     //{ 
      b = CQ.TryDequeue(out n); 
     //} while (!b); 

     argListBox.Items.Add(argstring); 
     argListBox.SelectedIndex = argListBox.Items.Count -1; 
     listBoxDeQueue.Items.Add(n.ToString()); 
     listBoxDeQueue.SelectedIndex = listBoxDeQueue.Items.Count - 1; 

    } 

    private void button_Start_Click(object sender, EventArgs e) 
    { 
     Thread methodThread1 = new Thread(new ThreadStart(TheThread1)); 
     methodThread1.Start(); 
     Thread methodThread2 = new Thread(new ThreadStart(TheThread2)); 
     methodThread2.Start(); 
    } 

    private void TheThread2() 
    { 
     eventGenerator2.Start(); 
    } 

    private void TheThread1() 
    { 
     eventGenerator1.Start(); 

    } 

    private void button_Stop_Click(object sender, EventArgs e) 
    { 
     eventGenerator1.Stop(); 
     eventGenerator2.Stop(); 
    } 

    private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     eventGenerator1.Stop(); 
     eventGenerator2.Stop(); 
    } 
} 

IncomingConnectionEventArgs

class IncomingConnectionEventArgs : EventArgs 
{ 
    public System.Windows.Forms.ListBox LB; 
    public int Property_Int { get; set; } 
    public string Property_String { get; set; } 

    public IncomingConnectionEventArgs(int argInt, string argString, 
     System.Windows.Forms.ListBox lb) 
    { 
     LB = lb; 
     Property_Int = argInt; 
     Property_String = argString; 
    } 
} 

EventGenerator

class EventGenerator 
{ 
    public delegate void RandomEventHandler(
     object sender, 
     IncomingConnectionEventArgs e); 

    public event RandomEventHandler OnRandomEvent; 

    public Random r = new Random(); 

    public ListBox listBox; 

    public bool Generate = true; 

    public ConcurrentQueue<int> CQ; 

    public EventGenerator(ConcurrentQueue<int> argCQ, ListBox argListBox) 
    { 
     CQ = argCQ; 
     listBox = argListBox; 
    } 

    public void Start() 
    { 
     Generate = true; 
     while (Generate) 
     { 
      Thread.Sleep(r.Next(100, 2000)); 
      RandomEvent(); 
     } 
    } 

    public void Stop() 
    { 
     Generate = false; ; 
    } 

    public void RandomEvent() 
    { 
     if (OnRandomEvent == null) 
     { 
      return; 
     } 

     int n = r.Next(1000, 10000); 
     CQ.Enqueue(n); 
     IncomingConnectionEventArgs Args = 
      new IncomingConnectionEventArgs(n, "", listBox); 

     OnRandomEvent(this, Args); 
    } 
} 

enter image description here

答えて

0

問題はランダムの使用です。 Randomの単一のインスタンスを使用したり、各インスタンスを異なる方法で明示的にシードしたりしない限り、Random.Next(...)を呼び出す2つのスレッドは通常、同じ値を生成します。

インスタンスをシードするためのより良い方法はこれです:

Random r = new Random(Guid.NewGuid().GetHashCode()); 
+0

が、私は時間のためにこれで苦労してきた、ありがとうございました。それは私の問題を解決した。 – TEDSON

+0

@TEDSON私は助けることができてうれしいです。 –

関連する問題