2014-09-26 111 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(); 
}