我帶你去一個刺在這個...
你可以看看它的CodePlex網站上的MVVM光源代碼。我要去這裏的相關方法(略註解這個職位的緣故)粘貼:
private void SendToTargetOrType<TMessage>(TMessage message, Type messageTargetType, object token)
{
var messageType = typeof(TMessage);
if (_recipientsOfSubclassesAction != null)
{
// Clone to protect from people registering in a "receive message" method
// Correction Messaging BL0008.002
var listClone =
_recipientsOfSubclassesAction.Keys.Take(_recipientsOfSubclassesAction.Count()).ToList();
foreach (var type in listClone)
{
List<WeakActionAndToken> list = null;
if (messageType == type
|| messageType.IsSubclassOf(type)
|| type.IsAssignableFrom(messageType))
{
lock (_recipientsOfSubclassesAction)
{
list = _recipientsOfSubclassesAction[type].Take(_recipientsOfSubclassesAction[type].Count()).ToList();
}
}
// Class A probably sends a message here from the UI thread
SendToList(message, list, messageTargetType, token);
}
}
if (_recipientsStrictAction != null)
{
// Class B grabs this lock on the background thread.
// Class A continues processing on the UI thread and arrives here.
// An attempt is made to grab the lock on the UI thread but it is
// blocked by the background thread & Class B which in turn is waiting
// on the UI thread. And here you have yourself a deadlock
lock (_recipientsStrictAction)
{
if (_recipientsStrictAction.ContainsKey(messageType))
{
var list = _recipientsStrictAction[messageType]
.Take(_recipientsStrictAction[messageType].Count())
.ToList();
// Class B sends its message here.
// Class C receives the message and does an Invoke on the UI thread
SendToList(message, list, messageTargetType, token);
}
}
}
RequestCleanup();
}
- A類可能是'子收件人發送UI線程上的消息拾起。
- B類是收到此消息並啓動後臺任務的收件人。
- 您的後臺任務隨後會發送一條包含「嚴格操作收件人」的郵件。
- B類在後臺線程上抓取'_recipientsStrictAction'鎖。
- B類將消息發送給C類,它在UI線程上執行一個調用。
- 這將調用塊,因爲UI線程仍在執行第一條消息。
- UI線程繼續執行,然後試圖搶在UI線程上的「_recipientsStrictAction」鎖。不幸的是,你的後臺線程(在UI線程上等待)已經有鎖。你現在處於死鎖狀態:(
可能想考慮在類C中做一個InvokeAsync而不是一個Invoke,我想你應該可以避免這個問題。
讓我想知道爲什麼MVVM燈會在鎖內發送消息。看起來像一個不太酷的事情要做。打完所有這些後,我去了解CodePlex站點,看起來像這個問題已被記錄: http://mvvmlight.codeplex.com/workitem/7581