异步while循环

时间:2014-01-27 15:48:46

标签: c# asynchronous windows-phone-8 background-process

我尝试在后台运行我的Windows手机应用程序。使用从离开应用程序开始的While循环,一切正常。但是当我再次进入应用程序时,应用程序会在无限循环中挂起并且不会加载。这就是我在while循环中编写条件的原因,但只要while循环正在运行,就不会考虑其他代码。是否有异步的while循环或其他东西来解决问题。

这是我在App.xaml.cs中的代码:

private void Application_Closing(object sender, ClosingEventArgs e)
{
    WhileLoop();
}

private void Application_Activated(object sender, ActivatedEventArgs e)
{
    Continue = false;
}

static bool Continue = false;

void WhileLoop()
{
   Continue = true;
   while(Continue == true)
   {
         //do something in background
   }
}

3 个答案:

答案 0 :(得分:2)

我很难通过在后台运行来猜测你的意思。如果你的意思是在锁定屏幕下运行,那么可以通过禁用IdleDetection,但这可能不是你想要实现的,因为我看到Closing Event等等。

在编写Windows Phone的其他情况下,您必须了解一些事项:

  • 正如@dcastro在评论中所说,当App关闭或重新启动时,你的时间有限,
  • 当App关闭时,没有方法,线程或任何东西将“存活”(或不应该)
  • 当应用程序被停用时 - 所有主题,BackroundWorkers(与您的应用程序连接的所有内容)都停止,MSDN说: When the user navigates forward, away from an app, after the Deactivated event is raised, the operating system will attempt to put the app into a dormant state. In this state, all of the application’s threads are stopped and no processing takes place, but the application remains intact in memory.
  • 另一个问题是当你的应用程序被Tombstoned,然后它的大部分资源被释放时,
  • 您可以使用Background Agents
  • 在后台执行某些操作
  • 或者您可以尝试在IsolatedStorage或PhoneApplicationService状态下保存应用程序的状态,(您可以阅读更多相关信息Here) - 在取消激活后保存,然后在激活时恢复

    希望这会有所帮助。

答案 1 :(得分:0)

您需要将循环移动到BackgroundWorker,因为在while循环启动时,它将占用UI线程中的CPU,这意味着没有其他消息将被处理,即您的{ {1}}事件。

问题是你试图突破在相同线程中运行的无限循环。如果您的Application_Activated循环位于不同的线程上(即不占用UI线程),那么您的代码应该可以工作。但是,我认为有更好的方法可以不使用

  1. 无限循环
  2. while字段
  3. 例如,更强大的方法是在[{1}}上保留对static的引用,然后在BackgroundWorker上保留对Application_Closing的引用,这样就可以了允许您使用BW中的Application_Activated属性来更安全地关闭后台进程。

答案 2 :(得分:-2)

    using System.Threading;

    ManualResetEventSlim waitEvent = new ManualResetEventSlim(false); // start in the unsignaled state

    async void Application_Closing(object sender, ClosingEventArgs e)
    {
        await MyLoop();    // execute asynchronously
        waitEvent.Wait();  // wait for a signal to continue
    }

    void Application_Activated(object sender, ActivatedEventArgs e)
    {
        waitEvent.Reset(); // set unsignaled
    }

    Task MyLoop()
    {
        while(true)
        {
            if(condition)
                break;
        }

        waitEvent.Set(); // signal the app to continue
    }