在c#中的线程之间传递数据

我发现很少有关于我的问题的问题,但是,我不能自己解决这个问题,所以我会试着在这里问一下。 我会粘贴代码,所以我认为它更容易解释。

public partial class Form1 : Form { public Form1() { InitializeComponent(); Thread thread = new Thread(new ThreadStart(StartCalculation)); thread.Start(); } private void Form1_Load(object sender, EventArgs e) { } public void StartCalculation() { List numbers = new List(); for (int i = 0; i  d.Text = textForLabel); } } } 
  • 我想从方法StartCalculation获取一个从不同的线程开始的访问。 我想从Form1访问该int列表(10秒后10个元素,20秒后20个元素等)。 那可能吗?
  • 是否可以在Form1()中创建列表然后在StartCalculation中更改它? 谢谢你的答案:)

编辑Groo- / –

 public partial class Form1 : Form { List list = new List(); // list of int values from game's memory public Form1() { InitializeComponent(); Thread thread = new Thread(new ThreadStart(refreshMemory)); thread.Start(); Thread thread2 = new Thread(new ThreadStart(checkMemory)); thread2.Start(); } private void Form1_Load(object sender, EventArgs e) { } public void refreshMemory() { while (true) { // ... refresh game's memory and then, refresh list // Thread.Sleep(100); } } public void checkMemory() { while (true) { // eg. if (list[0] == 5) {game:: move_right()}// Thread.Sleep(100); } } } 

我正在制作游戏机器人。 我希望它在不同的线程(更改内存列表)中读取游戏的内存,然后,使用其他一些方法(在不同的线程中),我想从该列表中读取并根据内存值执行游戏操作。 它工作(或似乎是)但如果你说它可能不安全,我想让它安全。

希望我在这里粘贴它并没有让自己变得愚蠢。

您需要某种forms的同步机制来修改多个线程之间的对象。 如果您不使用专门的线程安全集合(这些在.NET 4中可用),则需要使用监视器进行锁定。

通常,生产者/消费者模式的更合适的集合类型是Queue (FIFO集合),而不是List

具有显式锁定的Plain Queue

 private readonly object _lock = new object(); private readonly Queue _queue = new Queue(); private readonly AutoResetEvent _signal = new AutoResetEvent(); void ProducerThread() { while (ShouldRun) { Item item = GetNextItem(); // you need to make sure only // one thread can access the list // at a time lock (_lock) { _queue.Enqueue(item); } // notify the waiting thread _signal.Set(); } } 

在消费者线程中,您需要获取项目并处理它:

 void ConsumerThread() { while (ShouldRun) { // wait to be notified _signal.Wait(); Item item = null; do { item = null; // fetch the item, // but only lock shortly lock (_lock) { if (_queue.Count > 0) item = _queue.Dequeue(item); } if (item != null) { // do stuff } } while (item != null); // loop until there are items to collect } } 

从.NET 4开始,有一个ConcurrentQueue集合,一个线程安全的FIFO,它在访问它时不需要锁定并简化了代码:

ConcurrentQueue

 private readonly ConcurrentQueue _queue = new ConcurrentQueue(); void ProducerThread() { while (ShouldRun) { Item item = GetNextItem(); _queue.Enqueue(item); _signal.Set(); } } void ConsumerThread() { while (ShouldRun) { _signal.Wait(); Item item = null; while (_queue.TryDequeue(out item)) { // do stuff } } } 

最后,如果您只希望您的消费者线程定期获取块中的项目,您可以将其更改为:

具有阈值的ConcurrentQueue(10秒或10个项目)

 private readonly ConcurrentQueue _queue = new ConcurrentQueue(); void ProducerThread() { while (ShouldRun) { Item item = GetNextItem(); _queue.Enqueue(item); // more than 10 items? panic! // notify consumer immediately if (_queue.Count >= 10) _signal.Set(); } } void ConsumerThread() { while (ShouldRun) { // wait for a signal, OR until // 10 seconds elapses _signal.Wait(TimeSpan.FromSeconds(10)); Item item = null; while (_queue.TryDequeue(out item)) { // do stuff } } } 

这种模式非常有用,它很好地将它抽象为一个通用类,它将生成和消费委托给外部代码。 使其成为通用的将是一个很好的练习。

您还需要一个Stop方法,它可能会设置一个volatile bool标志,指示是时候停止,然后将信号设置为取消暂停消费者并允许它结束。 我会把这个留给你作为练习。

在这种情况下使用

 label.Invoke(..., textForLabel)