繁体   English   中英

C#线程查询

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM