线程睡眠在Windows Phone 7上无法正常工作

时间:2011-10-18 19:16:17

标签: c# windows-phone-7.1

我想让我的程序进入睡眠状态几秒钟。当我使用thread.sleep(x)整个程序没有响应。根据这篇文章 - >不负责3秒的http://msdn.microsoft.com/en-us/library/hh184840(v=VS.92).aspx申请未通过认证:/(我必须等待5秒)。有人知道这个问题的解决方案吗?

4 个答案:

答案 0 :(得分:7)

不要睡眠应用程序的主线程。相反,做任何你需要做的事情都需要在应用程序的后台线程中等待。

如果您在应用程序的主线程中放置了Thread.Sleep()调用,那么应用程序将无法响应幕后的UI消息循环,如您所见。这是因为您在处理一条消息(触发等待的UI事件)时阻止执行,因此不能处理该应用程序的其他消息。

相反,将此代码构造为异步运行。我猜测有一些方法包含大部分繁重的工作,包括睡眠。只要这不是一个事件处理程序(如果它是重构它),你可以设置第二个线程来运行这个方法,并添加一个方法将在它完成时调用的“回调”方法,这将使用结果。这是一个更多的工作,但它保持应用程序响应,它通常是良好的做法,尤其是在多核设备上(即使手机现在正在获得双核CPU)。有许多方法可以设置多线程操作。 Delegate.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.
}

答案 1 :(得分:4)

您需要重新考虑暂停时要做的事情。考虑到我们没有太多关于你试图通过这个暂停实现什么的信息,这有点难以说明,但我会举一个例子来说明如何在不必暂停整个应用程序的情况下获得想要的效果(你永远不应该这样做。)

假设您要下载文件A,然后等待5秒,然后下载文件B.您可以通过运行以下内容来执行此操作:

var file = downloadFileA();
new Thread((ThreadStart)delegate
{
    Thread.Sleep(5000);
    downloadFileB();
});

此外,让实际的下载调用async(如果它正在下载你正在做)是可以忍受的,只是为了确保你不会使GUI变得虚弱。

另外,您可以在后台线程中执行这两个下载:

new Thread((ThreadStart)delegate
{
    var file = downloadFileA();
    Thread.Sleep(5000);
    downloadFileB();
});

答案 2 :(得分:3)

免责声明:Thread.Sleep(n) 任何地方几乎都是“代码味道”,这意味着它表明应用中的其他代码也会成为一个问题。我通常完全避免使用它(我从未遇到过必须使用Thread.Sleep 的情况。)

但是,在您的情况下,Thread.Sleep(5000)的简单替换可能就是这样做:

for (int i = 0; i < 10; i++) {
    Thread.Sleep(500);
}

您将获得5秒的整体等待时间,但UI永远不会被锁定超过半秒。

答案 3 :(得分:1)

看起来像ThreadPool.QueueUserWorkItem的作业