我知道所有浏览器都是单线程的,不可能在JavaScript或Flash Player Thread.sleep中实现。我决定尝试在Silverlight中使用“ System.Threading”库实现Thread.Sleep。
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代码,我可以执行睡眠功能,但是我的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> 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()”破坏,在我的代码中,我将转到下一行并执行alert(“恢复”)。视频继续播放没有任何改变。现在,如果我使用Silverlight Thread.Sleep函数按下“暂停线程休眠”按钮。此时,视频将挂起,并且通过单击Internet Explorer,您可能会在Process Explorer中获得(未响应)状态。
我将更喜欢在COM,ActiveX或Silverlight对象中使用Thread.Sleep函数,但是我需要删除该线程死锁。与JavaScript模式对话框或警报中的行为相同。
提前谢谢了。
问候,
大卫·高夫曼
码:
index.html
PauseWin.html
最佳答案
您的代码完全按照您的要求进行操作:它正在使浏览器的UI线程处于休眠状态,这意味着您的浏览器无法再处理任何消息,因此可以有效地使浏览器在睡眠期间挂起。浏览器中的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();
}
}
关于javascript - 在Thread.Sleep的Internet Explorer中删除死锁?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5302557/