gpt4 book ai didi

c# - 如何在线程之间传递数据?

转载 作者:太空宇宙 更新时间:2023-11-03 21:10:45 26 4
gpt4 key购买 nike

我想将数据从一个线程移动到另一个线程,但我的代码只适用于我传递的第一个值,而不是将前 5 个值保存到列表中并在之后打印出来这是我的代码:

 private readonly ConcurrentQueue<int> _queue = new ConcurrentQueue<int>();
private readonly AutoResetEvent _signal = new AutoResetEvent(false);

public void Thread1()
{
List<int> values = new List<int>();
int lastInput;
StringBuilder sb = new StringBuilder();

while (values.Count < 5)
{
_signal.WaitOne();
_queue.TryDequeue(out lastInput);

values.Add(lastInput);
}
for (int i = 0; i < values.Count; i++)
{
sb.Append(String.Format("{0}\n", values[i]));
}
MessageBox.Show(sb.ToString());
}

private void button1_Click(object sender, EventArgs e)
{
Thread th1 = new Thread(Thread1);
th1.Start();

for (int i = 0; i < 8; i++)
{
_queue.Enqueue(i);
_signal.Set();
}
}

最佳答案

我明白您要做什么,@MarcGravell 的评论是正确的,@mariosangiorgio 所说的也是正确的。作为解决方法,您可以使用 Monitor Wait/Pulse 机制来代替。尝试以下操作:

    private readonly Queue<int> _queue = new Queue<int>();
private readonly object _locker = new object();

public void Thread1()
{
List<int> values = new List<int>();
int lastInput;
StringBuilder sb = new StringBuilder();

while (values.Count < 5)
{
lock (this._locker)
{
// wait until there is something in the queue
if (this._queue.Count == 0)
{
Monitor.Wait(this._locker);
}

// get the item from the queue
_queue.Dequeue(out lastInput);

// add the item to the list
values.Add(lastInput);
}
}

for (int i = 0; i < values.Count; i++)
{
sb.Append(String.Format("{0}\n", values[i]));
}
MessageBox.Show(sb.ToString());
}

private void button1_Click(object sender, EventArgs e)
{
Thread th1 = new Thread(Thread1);
th1.Start();

for (int i = 0; i < 8; i++)
{
lock (this._locker)
{
// put something in the queue
_queue.Enqueue(i);

// notify that there is something in the queue
Monitor.Pulse(this._locker);
}
}
}

因此,基本上您要做的是调用一个循环,该循环将尝试消耗总共 5 个项目。如果消费者线程看到队列中没有元素可以消费,它会一直等到生产者将一些元素放入队列中。一旦生产者将项目放入队列中,它就会告诉等待中的消费者线程它已准备就绪!然后,消费者线程将解除阻塞并消费队列中的任何项目。

另外,如果您考虑@mariosangiorgio 评论,您实际上是在使用并发集合。所以他是对的,实际上没有必要阻止。所以如果你想做你自己的阻塞/解除阻塞实验,你可以使用我的实现并只使用常规的Queue(非并发)。或者,就像@mariosangiorgio 所说的那样,只需删除 AutoResetEvent 并让 ConcurrentQueue 执行它的操作。

尽管如此,请记住,如果您不阻塞,您将不断循环并运行 CPU,直到某些东西真正出队

关于c# - 如何在线程之间传递数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37912481/

26 4 0
文章推荐: Javascript 可以将背景颜色更改为某些
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com