亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

避免使用鎖啟動新線程

避免使用鎖啟動新線程

C#
千萬里不及你 2022-06-18 17:32:17
這是否可以鎖定一個線程的方法并強制另一個線程走得更遠,而不是等到第一個線程完成?這個問題可以通過靜態線程或一些適當的模式來解決,其中一個實例是下面提到的服務。出于演示目的,可以使用如下靜態布爾值來完成。public class SomeService{  private readonly IRepository _repo;  public SomeService(IRepository repo)  {    _repo = repo;  }  private Thread threadOne;  public static bool isLocked { get; set; }  public void StartSomeMethod()  {    if(!isLocked)    {      threadOne = new Thread(SomeMethod);      isLocked = true;    }  }  public void SomeMethod()  {    while(true)    {      lots of time    }    ...    isLocked = false;  }}我想避免用戶意外單擊兩次啟動并且意外第二個線程在第一次完成后立即啟動的情況。
查看完整描述

3 回答

?
米脂

TA貢獻1836條經驗 獲得超3個贊

你可以使用鎖:)


object locker = new object();

void MethodToLockForAThread()

{

    lock(locker)

    {

      //put method body here

    }

}

現在的結果是,當這個方法被一個線程(任何線程)調用時,它會在鎖的開頭放置類似標志的東西:“停止!你不能再進一步了,你必須等待!” 就像十字路口的紅燈。當首先調用此方法的線程離開作用域時,然后在作用域的開頭,這個“紅燈”變為綠色。


如果您不想在該方法已被另一個線程調用時調用該方法,唯一的方法是使用 bool 值。例如:


object locker = new object();

bool canAccess = true;

void MethodToLockForAThread()

{

    if(!canAccess)

      return;


    lock(locker)

    {

      if(!canAccess)

        return;


      canAccess = false;            


      //put method body here


      canAccess = true;

    }

}

鎖定范圍內對 canAccess 的其他檢查是因為評論中的內容。不,它真的是線程安全的。這是一種在線程安全單例中可見的保護。


編輯


在與 mjwills 討論后,我必須改變主意,將更多內容轉變為 Monitor.TryEnter。你可以這樣使用它:


object locker = new object();

void ThreadMethod()

{

  if(Monitor.TryEnter(locker, TimeSpan.FromMiliseconds(1))

  {

     try

     {

       //do the thread code

     }

     finally

     {

       Monitor.Exit(locker);

     }

  } else

    return; //means that the lock has not been aquired

}

現在,由于某些異?;蚱渌€程已經獲取了鎖,因此無法獲取鎖。在第二個參數中,您可以傳遞線程等待獲取鎖的時間。我在這里給了很短的時間,因為你不希望其他線程在第一次做的時候做這項工作。所以這個解決方案似乎是最好的。


當另一個線程無法獲得鎖時,它會走得更遠而不是等待(它會等待1毫秒)。


查看完整回答
反對 回復 2022-06-18
?
哆啦的時光機

TA貢獻1779條經驗 獲得超6個贊

由于lock是圍繞類的特定于語言的包裝器Monitor,因此您需要Monitor.TryEnter:


public class SomeService

{

    private readonly object lockObject = new object();


    public void StartSomeMethod()

    {

        if (Monitor.TryEnter(lockObject))

        {

            // start new thread

        }

    }


    public void SomeMethod()

    {

        try

        {

            // ...

        }

        finally

        {

            Monitor.Exit(lockObject);

        }

    }    

}


查看完整回答
反對 回復 2022-06-18
?
慕的地6264312

TA貢獻1817條經驗 獲得超6個贊

您可以使用 aAutoResetEvent代替您的isLocked標志。


AutoResetEvent autoResetEvent = new AutoResetEvent(true);

public void StartSomeMethod()

{

    if(autoResetEvent.WaitOne(0))

    {

        //start thread

    }

}


public void SomeMethod()

{

    try

    {

        //Do your work

    }

    finally

    {

        autoResetEvent.Set();

    }

}


查看完整回答
反對 回復 2022-06-18
  • 3 回答
  • 0 關注
  • 121 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號