lock(myLockObject)
{
mySharedBuffer.Modfiy();
something.BeginDoStuff(new Action(delegate()
{
mySharedBuffer.Modify();
}));
}
,並提供給BeginDoStuff()調用回調回到另一個線程 - 召開/重新獲得回調時最終運行鎖? (我相信鎖定丟失,我需要再次鎖定,但無法找到的文檔這麼說)
lock(myLockObject)
{
mySharedBuffer.Modfiy();
something.BeginDoStuff(new Action(delegate()
{
mySharedBuffer.Modify();
}));
}
,並提供給BeginDoStuff()調用回調回到另一個線程 - 召開/重新獲得回調時最終運行鎖? (我相信鎖定丟失,我需要再次鎖定,但無法找到的文檔這麼說)
是持有/重新獲得回調時最終運行鎖?
不 - 沒有魔法在發生!
BeginXXX
立即返回並且控制退出lock
塊,鎖定被釋放。
如果您想要在回調中再次獲得鎖定,那麼您需要在那裏再設置一個lock
塊。
與所有鎖定一樣,這意味着在釋放鎖定時,必須將mySharedBuffer
對象保持在Consolidate狀態。此外,在釋放BeginXXX
之後的鎖定時間和您的回調再次獲取鎖定之間,此對象可能會被另一個線程修改。
如果BeginXXX
實現可以同步執行回調,然後調用堆棧將成爲像正常的順序碼和鎖仍將舉行。在這種情況下,如果您嘗試再次獲取回調中的鎖定,將立即獲得鎖定,因爲Monitor
允許在同一個線程上進行遞歸鎖定採集。
編號匿名代表不是lock
區域的標準。
通常BeginXXX方法執行異步操作,並立即返回。相應的EndXXX方法也可以等待操作完成。
如果要鎖定匿名委託,則需要使用嵌套鎖定。
lock(myLockObject)
{
mySharedBuffer.Modfiy();
something.BeginDoStuff(new Action(delegate()
{
lock (myLockObject) // nested locking here
{
mySharedBuffer.Modify();
}
}));
}
出於好奇:如果回調在同一個線程上同步完成? – markmnl
我已將此案例添加到我的答案中。 –