Pat*_*ryk 12 c# multithreading
我发现很少有关于我的问题的问题,但我仍然不能自己解决这个问题,所以我会试着在这里问一下.我会粘贴代码,所以我认为它会更容易解释.
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<int> numbers = new List<int>();
for (int i = 0; i <= 100; i++)
{
numbers.Add(i);
string textForLabel = i.ToString();
label.SafeInvoke(d => d.Text = textForLabel);
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑Groo-/ -
public partial class Form1 : Form
{
List<int> list = new List<int>(); // 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在制作游戏机器人.我想让它在不同的线程(更改内存列表)中读取游戏的内存,然后,使用其他一些方法(在不同的线程中),我想从该列表中读取并根据内存值执行游戏操作.它可以工作(或者似乎只是),但如果你说它可能不安全,我想让它安全.
希望我在这里粘贴它并没有让自己变得愚蠢.
Gro*_*roo 25
您需要某种形式的同步机制来修改多个线程之间的对象.如果您不使用专门的线程安全集合(这些在.NET 4中可用),则需要使用监视器进行锁定.
通常,生产者/消费者模式的更合适的集合类型是Queue(FIFO集合),而不是List:
具有显式锁定的Plain Queue
private readonly object _lock = new object();
private readonly Queue<Item> _queue = new Queue<Item>();
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();
}
}
Run Code Online (Sandbox Code Playgroud)
在消费者线程中,您需要获取项目并处理它:
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
}
}
Run Code Online (Sandbox Code Playgroud)
从.NET 4开始,有一个ConcurrentQueue<T>集合,一个线程安全的FIFO,在访问它时不需要锁定并简化代码:
ConcurrentQueue
private readonly ConcurrentQueue<Item> _queue = new ConcurrentQueue<Item>();
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后,如果您只希望您的消费者线程定期获取块中的项目,您可以将其更改为:
具有阈值的ConcurrentQueue(10秒或10个项目)
private readonly ConcurrentQueue<Item> _queue = new ConcurrentQueue<Item>();
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
这种模式非常有用,它很好地将它抽象为一个通用类,它将生成和消费委托给外部代码.使它成为通用的将是一个很好的练习.
您还需要一种Stop方法,该方法可能会设置一个volatile bool标志,指示是时候停止,然后将信号设置为取消暂停消费者并允许其结束.我会把这个留给你作为练习.