Удалить мертвую блокировку в Internet Explorer на Thread.Sleep? - PullRequest
0 голосов
/ 14 марта 2011

Я знаю, что все браузеры являются однопоточными и невозможными инструментами в JavaScript или Flash Player Thread.sleep. Я решил попробовать использовать библиотеку «System.Threading», реализующую Thread.Sleep в Silverlight.

App.xaml.cs

using System.Windows;
using System.Windows.Browser;
using System.Threading;

namespace ThreadSleep
{
    public partial class App : Application
    {

        public App()
        {
            InitializeComponent();
            HtmlPage.RegisterScriptableObject("App", this);
        }

        [ScriptableMember]
        public void Sleep(int mlsec)
        {
            Thread.Sleep(mlsec);
        }
    }
}

Итак, из кода JavaScript я могу выполнить функцию Sleep, но мой Internet Explorer зависает и не отвечает.

Вот мой пример:

Index.html

<HTML>
<BODY>
<SCRIPT LANGUAGE="JavaScript">
<!--
    var SleepInterval = 10000;

    function pause1(){
        window.showModalDialog("PauseWin.html", this, 'dialogWidth:255px; dialogHeight:105px; status:0; scroll:0;');
        alert("Resume");
    }
    function pause2(){
        var control = document.getElementById("SleepSL");
        control.Content.App.Sleep(SleepInterval);
        alert("Resume");
    }
    function tick(){
        var clock = document.getElementById("clock");
        if(clock) clock.innerHTML = new Date();
    }
    setInterval(tick, 1000);
//-->
</SCRIPT>
<INPUT TYPE="button" value="Pause Modal Dialog" onclick="pause1()">
<INPUT TYPE="button" value="Pause Thread Sleep" onclick="pause2()">
<BR><BR>

<!--Youtube Video -->
<iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/RWNcGBSP0Wg?autoplay=1" frameborder="0" allowfullscreen></iframe>

<!-- Silverlight Sleep API -->
<object id="SleepSL" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="1" height="1">
    <param name="source" value="SleepSL.xap"/>
    <param name="background" value="white" />
    <param name="minRuntimeVersion" value="4.0.50826.0" />
    <param name="autoUpgrade" value="true" />
    <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" style="text-decoration:none">
        <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
    </a>
</object>
<BR><BR>

<DIV ID="clock"/>
</BODY>
</HTML>

PauseWin.html

<html>
<title>Pause Window</title>
<style>body{margin-top:10}</style>
<body scroll="no">

<center style='font-size:14px;font-weight:bold'>
    The window will automatically <br> close in <span id="time"></span>&nbsp;second(s).
</center>

<script type="text/javascript">
    var ms = window.dialogArguments.SleepInterval;

    function wait(){
        var span = document.getElementById('time');
        span.innerHTML = (ms / 1000);
        setInterval(function(){ closeWindow(); }, ms);
        setInterval(function(){ ms -= 1000; if(ms > 0) span.innerHTML = (ms / 1000); }, 1000);
    }

    function closeWindow(){
        window.close()
    }
    wait();
</script>
</body>
</html>

Выполняя файл index.html, я запускаю видео и таймер YouTube. Когда я нажал " Пауза модального диалога ", таймер останавливается, но видео продолжает воспроизводиться, через 10 секунд всплывающее окно модального всплывающего окна с помощью JS "window.close ()" и в моем коде я перехожу к следующему линия и выполнение оповещения (« Резюме »). Ничего не меняется, видео продолжает воспроизводиться. Теперь, если я нажму кнопку Pause Thread Sleep , используя функцию Silverlight Thread.Sleep. В это время видео зависает, и, нажав на Internet Explorer, вы можете получить ( Не ответил ) состояние в Process Explorer.

Я предпочитаю использовать функцию Thread.Sleep в объектах COM, ActiveX или Silverlight, но мне нужно удалить эту блокировку потока. Получите то же поведение, что и в JavaScript Modal Dialog или Alert.

Заранее большое спасибо.

С уважением,

Дэвид Гофман

код:

index.html

PauseWin.html

Ответы [ 2 ]

1 голос
/ 25 мая 2011

Вы можете сделать это:

function begin() { /* do stuff... */ }
function afterWait() { /* rest of my code...*/ }

begin();
setTimeout(afterWait, 10000);

setTimeout фактически остановил ваш JavaScript на 10 секунд, и браузер все еще может работать

1 голос
/ 15 марта 2011

Ваш код делает именно то, что вы говорите: он спит в потоке пользовательского интерфейса вашего браузера, что означает, что ваш браузер не может обрабатывать больше сообщений, поэтому он фактически зависает ваш браузер на время сна.Thread.Sleep () в браузере - это смерть: просто не делайте этого, будь то в Silverlight или любом другом фреймворке.

Лучше было бы сделать шаг назад и спросить себя, почему вы хотите что-то спать,а затем выяснить разумный асинхронный способ сделать это.Будучи брошенным в асинхронный мир Silverlight несколько лет назад, я понимаю, что сначала это может дезориентировать, но я также могу засвидетельствовать, что всегда находил достаточно чистые способы сделать это правильно.

Другой способскажем так: если вы не можете понять, как сделать то, что вам действительно нужно, напишите вопрос о , что , и вы, вероятно, получите некоторую помощь здесь.

Например, если вы просто хотите подождать 'n' секунд и затем выполнить обратный вызов, вы можете использовать вспомогательный класс, подобный этому:

public class ThreadingHelper
{
    public static void SleepAsync(int millisecondsToSleep, Action action)
    {
        var timer = new Timer(o => action());
        timer.Change(millisecondsToSleep, Timeout.Infinite);
    }

    public static void SleepAsync(TimeSpan interval, Action action)
    {
        SleepAsync((int)interval.TotalMilliseconds, action);
    }

    public static void DispatcherSleepAsync(int millisecondsToSleep, Action action)
    {
        var interval = TimeSpan.FromMilliseconds(millisecondsToSleep);
        DispatcherSleepAsync(interval, action);
    }

    public static void DispatcherSleepAsync(TimeSpan interval, Action action)
    {
        var timer = new DispatcherTimer();
        EventHandler timerHandler = null;
        timerHandler = (s, e) =>
        {
            timer.Tick -= timerHandler;
            if (action != null)
            {
                action();
            }
        };
        timer.Tick += timerHandler;
        timer.Interval = interval;
        timer.Start();
    }

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