[英]C# Threading Query
我对线程技术还很陌生,所以不确定自己是否做对了,但是希望获得一些帮助。 当用户单击鼠标时,我将运行以下代码; 它基本上运行一些寻路代码并移动播放器。
但是,我的问题是当线程运行时再次单击鼠标时,会引起问题。 当第二次到达此代码时,是否有办法停止前一个线程并启动一个新线程?
private void checkMouse()
{
mouseCommand mc = new mouseCommand();
Thread oThread = new Thread(() => mc.leftClick(Mouse.GetState().X,Mouse.GetState().Y));
oThread.Start();
}
也许这样的事情对您有用?
private object lock_object - new object();
private Thread oThread = new Thread();
private void checkMouse()
{
lock(lock_object)
{
if (oThread.ThreadState != ThreadState.Running)
{
mouseCommand mc = new mouseCommand();
oThread = new Thread(() => mc.leftClick(Mouse.GetState().X,Mouse.GetState().Y));
oThread.Start();
}
}
}
有几种方法可以做到这一点。
在学习线程时,最简单的方法是应该首先了解的是锁。 有一个用于锁定此object
,以及所有相关的动作(如果它们一起发生也会导致问题):
private object lockObj = new object();
private static void DoLClick()
{
lock(lockObj)
{
mouseCommand mc = new mouseCommand();
mc.leftClick(Mouse.GetState().X,Mouse.GetState().Y));
}
}
private void checkMouse()
{
Thread oThread = new Thread(DoLClick);
oThread.Start();
}
这样做的好处是可以防止线程互相踩到脚趾。
缺点是并发丢失(所有这些线程都在互相等待,而不是做某事)和死锁的风险(如果线程A具有锁1并需要锁2,而线程B具有锁2并需要锁1,则您被卡住)。
它仍然是最简单的方法。 通常,即使您将需要使用另一种方法,也值得从一些定义广泛的锁开始,然后再更改为较窄的锁(即,覆盖较少代码的锁)或以后使用其他方法。
另一种可能性是拥有一个锁,但是可以使用Monitor.TryEnter()
并使其超时(可能为零),而不是使用lock(){}
来获取它,如果没有得到,就放弃:
private object lockObj = new object();
private static void DoLClick()
{
if(!Monitor.TryEnter(lockObj, 0))
return; // Just do nothing if we're busy.
try
{
mouseCommand mc = new mouseCommand();
mc.leftClick(Mouse.GetState().X,Mouse.GetState().Y));
}
finally
{
Monitor.Exit(lockObj);
}
}
private void checkMouse()
{
Thread oThread = new Thread(DoLClick);
oThread.Start();
}
缺点是您没有完成第二项任务。 好处是,您通常不希望某些事情已经完成,而您可以免费获得。
其他一些方法是这种方法的变体,其中有一个线程安全的对象描述了要执行的任务。 它可以是需要执行的操作的整数,您可以使用Interlocked.Increment()
和Interlocked.Decrement()
进行更改,或者可以是描述需要执行任务的对象的ConcurrentQueue
。 然后,您可能会使未能获得锁定的线程添加到该线程中,而获得锁定的线程将在线程完成时接管该线程的工作。 或者,您可能有一个专用线程来继续寻找工作,并在AutoResetEvent
耗尽时等待它-使它工作的线程(添加到队列中)设置该事件以确保它不只是在做没有。
所有这些可能性(以及更多)都值得学习,并且有其应有的地位,但是第一个带有lock
建议是第一个需要学习的建议。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.