2012-03-28 55 views
0

我們有一個具有主窗口的應用程序,它可以在新瀏覽器中啓動多個其他窗口。我們使用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循環,或者我是否從根本上誤解了某些內容?或者錯過了一些顯而易見的東西在我面前凝視着我?

回答

0

我找到了一種工作方式。但是,這並不能真正「解決」這個問題,就我個人而言,這也只是支持Internet Explorer。

function WindowCloseEventHandler() 
{ 
    var app = // get silverlight app handle... 
    app.doAutoSave(); 
    var params = 'whatever you need'; 
    var args = new Object(); 
    args.hwnd = window; 
    window.showModalDialog('blocker.aspx',args,params); 
} 

function checkAutoSave() 
{ 
    var app = // get silverlight app handle... 
    return app.autosavecomplete(); 
} 

然後在blocker.aspx我們顯示靜態「執行註銷處理程序」類型的消息,並做:

function timerTick() 
{ 
    if(window.dialogArguments.hwnd.checkAutoSave()) { 
     window.close(); 
    } else { 
     setTimeout(timerTick, 500); 
    } 
} 

並開始窗口負載定時器。

通知子窗口的silverlight應用程序啓動自動保存,然後在完成後通知父項。然後我們從模態對話框中查詢父對象的狀態,該對話框阻止我們連接到正文的onclose事件的WindowCloseEventHandler()的終止。

這是hacky和可怕的,但它意味着silverlight保持異步,我們正在使用JavaScript計時器,所以JavaScript不加載系統。

當然,如果用戶關閉模態對話,則存在潛在的問題。

0

這聽起來像是由於進行同步/異步而導致的比賽情況的微妙變化。在queston 的過程中是否還有接收到來自窗口的通知,他們已收到該消息並正在關閉?一旦接收到所有的計數器消息,那麼主應用程序可以關閉而不需要在最後(?)等待。

+0

問題在於onclose處理程序需要同步響應。只要我允許它異步並等待所有參與方做出響應,主事件處理程序就會完成處理,並關閉窗口以創建競爭條件。 – THEMike 2012-04-03 12:14:54