【发布时间】:2017-06-26 14:52:11
【问题描述】:
我的要求是将项目插入队列并进行处理,但应先添加项目,然后再处理它们(因为在处理项目之前需要设置一些其他的东西. 这是我到目前为止所做的编码。
#region Variables Declarations
private Thread threadTask = null;
ConcurrentQueue<string> concurrentQueue = new ConcurrentQueue<string>();
string currentSeqNo;
string previousSeqNo = "-1";
#endregion
private void test1_Load(object sender, EventArgs e)
{
AddItems();
if (threadTask == null)
{
threadTask = new Thread(Kick);
Thread.Sleep(5000);
threadTask.Start();
}
}
private void AddItems()
{
for (Int64 i = 100000; i < 300000; i++)
{
concurrentQueue.Enqueue(i.ToString());
this.Invoke(new MethodInvoker(delegate()
{
label1.Text = i.ToString();
label1.Update();
}));
}
}
private void Kick()
{
while (true)
{
int recordCountNew = concurrentQueue.Count();
if (recordCountNew != 0)
{
RemoveItems();
}
}
}
private void RemoveItems()
{
string item;
while (concurrentQueue.TryDequeue(out item))
{
this.Invoke(new MethodInvoker(delegate()
{
label2.Text = item;
label2.Update();
}));
currentSeqNo = item; // second time does not start wil 100000
if (previousSeqNo != "-1")
{
if (long.Parse(currentSeqNo) != long.Parse(previousSeqNo) + 1)
{
Reconnect();
}
else
{
//Process item
previousSeqNo = currentSeqNo;
}
}
else
{
//Process item
previousSeqNo = currentSeqNo;
}
}
}
private void Reconnect()
{
currentSeqNo = "";
previousSeqNo = "-1";
string someItem;
while (concurrentQueue.Count > 0)
{
concurrentQueue.TryDequeue(out someItem);
}
this.Invoke(new MethodInvoker(delegate()
{
label1.Text = "";
label2.Text = "";
label1.Update();
label2.Update();
}));
AddItems();
if (threadTask == null)
{
threadTask = new Thread(Kick);
threadTask.Start();
}
}
private void button1_Click_1(object sender, EventArgs e)
{
Reconnect();
}
重现问题:运行应用程序并在中间单击按钮。现在队列应该再次从 100000 开始,但它显示的数字大于 100000。
请告知单击按钮后如何释放所有资源以重新开始。虽然我将它们设置为默认值并清除队列,但是当调用“RemoveItems”方法时,它仍然显示 currentSeqNo 中的旧值。
【问题讨论】:
-
如果您的删除项目比您添加的项目更快,您的队列提前结束,您应该考虑使用
BlockingCollection<string>,它使用ConcurrentQueue作为默认支持集合。 -
我试过 BlockingCollection 但情况还是一样。
-
为什么不创建一个新的 ConcurrentQueue 并交换引用?
-
ConcurrentQueue
wssMessagesQueue = new ConcurrentQueue (); concurrentQueue = wssMessagesQueue; -
试过这个.. 但还是不太幸运
标签: c# multithreading winforms