Спящий поток не работает на Windows Phone7 - PullRequest
1 голос
/ 18 октября 2011

Я хочу перевести мою программу в спящий режим на пару секунд. Когда я использую thread.sleep (x), вся программа не отвечает. Согласно этой статье -> http://msdn.microsoft.com/en-us/library/hh184840(v=VS.92).aspx приложение, которое не отвечает за 3 секунды, не проходит сертификацию: / (мне нужно подождать 5 секунд). Кто-нибудь знает решение этой проблемы?

Ответы [ 4 ]

7 голосов
/ 18 октября 2011

Не спите основной поток вашего приложения. Вместо этого делайте все, что вам нужно, что требует ожидания в фоновом потоке вашего приложения.

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

Вместо этого структурируйте этот код для асинхронного запуска. Я предполагаю, что есть какой-то метод, который содержит большую часть тяжелой работы, включая сон. Пока это не обработчик событий (его рефакторинг, если он есть), вы можете настроить второй поток для запуска этого метода и добавить метод «обратного вызова», который будет вызывать метод после его завершения, который обновит пользовательский интерфейс с помощью Результаты. Это немного больше работы, но она поддерживает отзывчивость приложения, и, как правило, это хорошая практика, особенно на многоядерных устройствах (в настоящее время даже телефоны получают двухъядерные процессоры). Есть много способов настроить многопоточные операции. 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.
}
4 голосов
/ 18 октября 2011

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

Скажем, вы хотите загрузить файл A, затем подождите 5 секунд, а затем загрузить файл B. Вы делаете это, выполнив что-то вроде этого:

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

ТакжеЖелательно, чтобы фактические асинхронные вызовы загрузки выполнялись (если выполняется загрузка, которую вы делаете), просто чтобы убедиться, что вы не отключаете графический интерфейс.

Альтернативно, вы можете выполнять обе загрузки вфоновый поток, как это:

new Thread((ThreadStart)delegate
{
    var file = downloadFileA();
    Thread.Sleep(5000);
    downloadFileB();
});
3 голосов
/ 18 октября 2011

Отказ от ответственности: Thread.Sleep(n) в любом месте в значительной степени является «запахом кода», то есть это показатель того, что другой код в приложении также будет проблемой.Я вообще вообще избегаю его использования (я никогда не сталкивался со сценарием, в котором Thread.Sleep должен использоваться).

В вашем случае, однако, простая замена для Thread.Sleep(5000) может быть просто сделать это:

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

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

1 голос
/ 18 октября 2011

Похоже на работу для ThreadPool.QueueUserWorkItem

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