2014-09-26 157 views
0

我有一個線程。在某個時刻,我想要做的是檢查某個鎖是否可用。如果它是免費的,我希望線程繼續其快樂的方式。如果它不是免費的,我想等到它是免費的,但實際上並沒有獲得鎖定。等待鎖定被釋放

這是到目前爲止我的代碼:

private object LockObject = new Object(); 

async void SlowMethod() { 
    lock (LockObject) { 
    // lotsa stuff 
    } 
} 

void AppStartup() { 
    this.SlowMethod(); 
    UIThreadStartupStuff(); 
    // now, I want to wait on the lock. I don't know where/how the results 
    // of SlowMethod might be needed. But I do know that they will be needed. 
    // And I don't want to check the lock every time. 
} 
+0

見http://stackoverflow.com/questions/12033725/c-sharp-how-to-detect-an-object-is-already-locked – dizel3d 2014-09-26 20:29:05

+0

@ dizel3d這是一個不同的操作。確定鎖是否空閒與等待空閒而不獲取鎖是不同的。 – Servy 2014-09-26 20:30:30

+0

如果您的示例代碼代表您的真實問題,那麼您可以對'SlowMethod'返回的任務執行「等待」。 – 2014-09-26 20:37:15

回答

2

我覺得你有經典的XY問題。我想你想要的是與你開始一個任務SlowMethod,然後繼續它與UIThreadStartupStuff是UI線程。

Task.Factory.StartNew(()=>SlowMethod()) 
    .ContinueWith(t=>UIThreadStartupStuff(), TaskScheduler.FromCurrentSynchronizationContext()); 

或異步/等待(讓你SlowMethod返回任務)

try 
{ 
    await SlowMethod(); 
} 
catch(...) 
{} 
UIThreadStartupStuff(); 
-1

我可能不會得到你想要達到的目標,但爲什麼上了鎖迫不及待「正常」? 畢竟,如果你可以拿着它,這是一個明確的鎖定免費標誌。 另外,如果它很重要,您可以立即發佈它。

void AppStartup() { 
    this.SlowMethod(); 
    UIThreadStartupStuff(); 

    // now, I want to wait on the lock. I don't know where/how the results 
    // of SlowMethod might be needed. But I do know that they will be needed. 
    // And I don't want to check the lock every time. 

    lock (LockObject) { 
     // nothing, you now know the lock was free 
    } 

    // continue... 

}

2

你不想在這裏使用的鎖。你需要一個事件。 ManualResetEventAutoResetEvent

請記住,鎖用於互斥。事件用於信令。

你有你的SlowMethod設置完成後的事件。例如:

private ManualResetEvent DoneEvent = new ManualResetEvent(false); 

async void SlowMethod() { 
    // lotsa stuff 
    // done with lotsa stuff. Signal the event. 
    DoneEvent.Set(); 
} 

void AppStartup() { 
    this.SlowMethod(); 
    UIThreadStartupStuff(); 

    // Wait for the SlowMethod to set the event: 
    DoneEvent.WaitOne(); 
}