线程睡眠在Windows Phone 7上不能很好地工作
本文关键字:不能 很好 工作 Phone Windows 线程 | 更新日期: 2023-09-27 18:11:41
我想让我的程序休眠几秒钟。当我使用thread.sleep(x)
时,整个程序没有响应。根据这篇文章-> http://msdn.microsoft.com/en-us/library/hh184840(v=VS.92).aspx不负责3秒的应用程序没有通过认证:/(我必须等待5秒)。
不要让应用程序的主线程休眠。相反,做任何需要在应用程序的后台线程中等待的事情。
如果你在应用程序的主线程中调用thread . sleep(),应用程序将在后台对UI消息循环没有响应,如你所见。这是因为你在处理一个消息(触发等待的UI事件)时阻塞了执行,所以应用程序的其他消息无法处理。
相反,将此代码结构为异步运行。我猜有一些方法可以解决大部分繁重的工作,包括睡眠。只要这不是一个事件处理程序(重构它),您就可以设置第二个线程来运行该方法,并添加一个"回调"方法,该方法将在完成时调用该方法,该方法将使用结果更新UI。这需要更多的工作,但它可以保持应用程序的响应性,这通常是一个很好的实践,特别是在多核设备上(甚至现在的手机也有双核cpu)。有许多方法可以设置多线程操作。委托。BeginInvoke是我最喜欢的:
public delegate void BackgroundMethod()
public void HandleUITrigger(object sender, EventArgs e)
{
//we'll assume the user does something to trigger this wait.
//set up a BackgroundMethod delegate to do our time-intensive task
BackgroundMethod method = DoHeavyLifting;
//The Delegate.BeginInvoke method schedules the delegate to run on
//a thread from the CLR's ThreadPool, and handles the callback.
method.BeginInvoke(HeavyLiftingFinished, null);
//The previous method doesn't block the thread; the main thread will move on
//to the next message from the OS, keeping the app responsive.
}
public void DoHeavyLifting()
{
//Do something incredibly time-intensive
Thread.Sleep(5000);
//Notice we don't have to know that we're being run in another thread,
//EXCEPT this method cannot update the UI directly; to update the UI
//we must call Control.Invoke() or call a method that Invokes itself
ThreadSafeUIUpdate();
}
public void ThreadSafeUIUpdate()
{
//A simple, thread-safe way to make sure that "cross-threading" the UI
//does not occur. The method re-invokes itself on the main thread if necessary
if(InvokeRequired)
{
this.Invoke((MethodInvoker)ThreadSafeUIUpdate);
return;
}
//Do all your UI updating here.
}
public void HeavyLiftingFinished()
{
//This method is called on the main thread when the thread that ran
//DoHeavyLifting is finished. You can call EndInvoke here to get
//any return values, and/or clean up afterward.
}
你需要重新考虑一下你暂停的目的。这有点难说,因为我们没有太多关于这个暂停的信息,但我在这里举一个例子来说明你如何在不暂停整个应用程序的情况下获得想要的效果(这是你永远不应该做的)。
假设您想下载文件A,然后等待5秒,然后下载文件b。您可以运行如下命令:
var file = downloadFileA();
new Thread((ThreadStart)delegate
{
Thread.Sleep(5000);
downloadFileB();
});
同样,最好让实际的下载调用异步(如果你正在下载),只是为了确保你没有冻结GUI。
或者,您也可以像这样在后台线程中完成这两个下载:
new Thread((ThreadStart)delegate
{
var file = downloadFileA();
Thread.Sleep(5000);
downloadFileB();
});
免责声明:Thread.Sleep(n)
任何地方都是一种"代码气味",这意味着它表明应用程序中的其他代码也将是一个问题。我通常避免使用它(我从来没有遇到过必须使用Thread.Sleep
的场景)。
但是,在您的情况下,Thread.Sleep(5000)
的一个简单的插入式替换可能只是这样做:
for (int i = 0; i < 10; i++) {
Thread.Sleep(500);
}
您将实现5秒的总等待时间,但UI将永远不会被锁定超过半秒。
看起来像是ThreadPool的工作。QueueUserWorkItem