簡體   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