我不太清楚如何詞這一點,所以我就貼上我的代碼,並提出這樣的問題:鎖定傳遞給其他線程的對象會發生什麼?
private void remoteAction_JobStatusUpdated(JobStatus status) {
lock (status) {
status.LastUpdatedTime = DateTime.Now;
doForEachClient(c => c.OnJobStatusUpdated(status));
OnJobStatusUpdated(status);
}
}
private void doForEachClient(Action<IRemoteClient> task) {
lock (clients) {
foreach (KeyValuePair<RemoteClientId, IRemoteClient> entry in clients) {
IRemoteClient clientProxy = entry.Value;
RemoteClientId clientId = entry.Key;
ThreadPool.QueueUserWorkItem(delegate {
try {
task(clientProxy);
#pragma warning disable 168
} catch (CommunicationException ex) {
#pragma warning restore 168
RemoveClient(clientId);
}
});
}
}
}
假設其修改status
對象的任何其他代碼將在首先獲得鎖。
由於status
對象是通過傳遞一路多ThreadPool
線程,以及調用ThreadPool.QueueUserWorkItem
將前實際完成的任務完成,我會確保同一status
對象被髮送到所有客戶端?
換句話說,lock (status)
語句何時「過期」或導致其鎖被釋放?
編輯這個問題,希望能夠澄清我的措辭。我忘了說任何修改我的'status'對象的其他代碼將首先獲取它的鎖。無論如何,這回答我的問題,謝謝。 – jnylen 2010-09-21 14:34:48
一個問題,但是:你說「你不能將鎖傳遞給其他線程。」但作爲一個人爲的例子,說我做了'lock(someObject){Thread t = new Thread(new ThreadStart(doSomething)); t.Start(); t.Join(); }'那麼鎖就會被有效地傳遞給我的另一個線程,因爲它會一直保持線程運行的整個時間,對吧? – jnylen 2010-09-21 14:42:27
@jnylen:我刪除了你從我的回答中引用的文字,因爲它沒有什麼意義。關於你的例子:只要新線程不嘗試「鎖定(someObject)」,答案是肯定的。否則,你有一個死鎖,兩個線程都被阻塞,等待另一個線程。 – 2010-09-21 15:07:48