我无法弄清楚我的C#代码有什么问题。
我试图学习如何在System.Collections.Concurrent命名空间中使用ConcurrentQueue类。
为了做到这一点,我在不同的线程中创建了同一个类的2个实例,并向构造函数传递了一个不同的Listbox控件。
我希望EventGenerator的每个类实例以随机的间隔引发事件,更新Listbox,它们是随机生成的数字传递的,并将该数字添加到ConcurrentQueue中,它也传递给构造函数。
在我的主线程中,是DeQueue由两个衍生线程对其进行EnQueue的对象的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;
}
}
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);
}
}
答案 0 :(得分:0)
问题在于您使用Random。除非您使用Random的单个实例或以不同方式显式地为每个实例设定种子,否则调用Random.Next(...)的两个线程通常会生成相同的值。
为您的实例设定种子的更好方法是:
Random r = new Random(Guid.NewGuid().GetHashCode());