我們有一個具有主窗口的應用程序,它可以在新瀏覽器中啓動多個其他窗口。我們使用silverlight應用程序作爲主窗口中的協調服務器,以關閉作爲應用程序一部分的所有窗口,而不管它們是以何種方式打開的(我們無法保證它是通過window.open保證的,因此並不總是有在JavaScript中的窗口句柄)。同步使用LocalMessageSender
註銷時,我們希望發信號通知所有其他窗口執行自動保存(如有必要),然後關閉。
所以所有的窗戶都有一個silverlight應用程序,它們使用localmessagesenders進行協調。然而,這些都是異步的:
private void ProcessAutosave()
{
foreach (string s in _windows)
{
SendMessage(s, "notify-logout");
}
// code here quoted later...
}
// sendasynch doesn't send until the method terminates, so have to do it in it's own function.
private void SendMessage(string to, string message)
{
var lms = new LocalMessageSender(to);
lms.SendCompleted += new EventHandler<SendCompletedEventArgs>(SenderSendCompleted);
lms.SendAsync(message);
}
由於ProcessAutosave從無法取消一個javascript onunload事件中調用,我們需要這是同步的,不完整的,我們必須從每個子窗口處理的響應之前所以會話狀態仍然有效等。
在SenderSendCompleted中,我們從_windows中刪除項目,當他們說他們已經完成。
所以我說在結束一個循環:
while(_windows.Count > 0) {
Thread.Sleep(1)
}
然而,永遠不會終止,除非我把一個迭代計數器就可以了。
我是編譯器優化的受害者,這意味着SenderSendCompleted中的更改不會影響while循環,或者我是否從根本上誤解了某些內容?或者錯過了一些顯而易見的東西在我面前凝視着我?
問題在於onclose處理程序需要同步響應。只要我允許它異步並等待所有參與方做出響應,主事件處理程序就會完成處理,並關閉窗口以創建競爭條件。 – THEMike 2012-04-03 12:14:54