[英]Multiple class instances raising same event
我在弄清楚C#代碼出什么問題時遇到了麻煩。
我正在嘗試學習如何在System.Collections.Concurrent命名空間中使用ConcurrentQueue類。
為此,我在不同的線程中創建了兩個相同類的實例,並將不同的Listbox控件傳遞給構造函數。
我期望EventGenerator的每個類實例以隨機的間隔引發事件,更新Listbox並使用隨機生成的數字進行傳遞,並將該數字添加到ConcurrentQueue中,該ConcurrentQueue也傳遞給構造函數。
在我的主線程中,是將兩個生成的線程都排隊到其上的對象的ConcurrentQueue取消排隊的方法。
但是我得到的是2個EnQueue列表框顯示相同的數據,而DeQueue列表框似乎報告已將它們都取消隊列。
如果我的描述不夠好,我深表歉意,並附上我的代碼,以及指向表單圖像的鏈接,以防它可能更好地幫助可視化我要執行的操作...
形成
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;
}
}
事件產生器
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);
}
}
問題在於您使用隨機數。 除非您使用Random的單個實例或以不同的方式顯式播種每個實例,否則調用Random.Next(...)的兩個線程通常會生成相同的值。
播種實例的更好方法是:
Random r = new Random(Guid.NewGuid().GetHashCode());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.