Использование LocalMessageSender синхронно - PullRequest
0 голосов
/ 28 марта 2012

У нас есть приложение, у которого есть главное окно, оно может запускать несколько других окон в новых браузерах.Мы используем приложение silverlight в качестве координирующего сервера в главном окне, чтобы закрыть все окна, которые являются частью приложения, независимо от того, как они открываются (мы не можем гарантировать, что это было через window.open, поэтому не всегда имеемдескриптор окна в javascript).

При выходе из системы мы хотим подать сигнал всем другим окнам на автоматическое сохранение, если необходимо, затем закрыть.

Итак, все окнаесть приложение Silverlight, они координируются с использованием местных сообщений сообщений.Однако они асинхронные:

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 вызывается из события onunload javascript, которое нельзя отменить, нам нужно, чтобы это было синхронно и не завершено до того, как мы обработаем ответ от каждого подпрограммыокно, чтобы состояние сеанса оставалось действительным и т. д.

В SenderSendCompleted мы удаляем элементы из _windows, когда они сказали, что все сделано.

Поэтому я добавил цикл в конце:

while(_windows.Count > 0) {
 Thread.Sleep(1)
}

Однако это никогда не завершается, если я не добавлю на него счетчик итераций.

Являюсь ли я жертвой оптимизации компилятора, то есть изменения в SenderSendCompleted не влияют на цикл while,или я что-то в корне неправильно понял?Или упустил что-то очевидное, которое смотрит мне в лицо?

Ответы [ 2 ]

0 голосов
/ 03 апреля 2012

Я нашел способ обойти.Тем не менее, это в действительности не «решает» проблему в целом, в моем случае, который также поддерживает только 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 дочернего окна получают уведомление о запуске автосохранения, а затем уведомляют родителя о завершении.Затем мы опрашиваем статус родителя из модального диалога, который блокирует завершение WindowCloseEventHandler (), которое мы связали с событием onclose тела.

Это хакерский и ужасный, но это означает, что silverlight остается асинхронными мы используем таймер javascript, поэтому javascript не загружает систему.

Конечно, если пользователь закрывает модальное диалоговое окно, существует вероятность возникновения проблемы.

0 голосов
/ 30 марта 2012

Звучит как тонкий вариант ситуации гонки из-за синхронизации / асинхронности.Не мог ли процесс в queston также получать уведомления от окон, что они получили сообщение и закрываются?После получения всех сообщений счетчика основное приложение может завершить работу без ожидания «занято» в конце (?).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...