Windows Phone 8.1应用中的后台线程

4

我正在开发一款Windows Phone 8.1购物应用程序。在应用程序中,我有一个持续运行的线程,它会下载用户的购物篮并将其保存在本地缓存中以提高性能。

到目前为止,我的代码类似于以下内容:

while(UserLoggedIn)
{
    await Networking.getBasket();
    await Task.Delay(5000);
}

这个线程是在应用程序恢复时启动的。我的问题是:如何最好地控制这样一个线程?在应用程序恢复时,它似乎非常缓慢,有时会阻塞UI线程,尽管它完全是异步的。我该如何提高性能?

编辑

根据Romasz的建议,我使用了一个计时器,就像这样:

声明它:

Timer _getBasketTimer;

在应用程序的构造函数中进行初始化:

_getBasketTimer = new Timer(getBasketCallback, null, 5000, Timeout.Infinite);

定义回调函数:

private async void getBasketCallback(Object state)
{
    if (JSONCache.getSessionID() != "" && Networking.LoginInProgress == false)
        await Networking.getBasket();

    //The Change method may be called when the Timer object is already Disposed (I debugged it, and the exception did occur sometimes)
    try
    {
        _getBasketTimer.Change(5000, Timeout.Infinite);
    }
    catch(ObjectDisposedException)
    {

    }
}

在应用程序暂停事件中处理它,这样当应用程序被挂起时,线程就不会运行:
_getBasketTimer.Dispose();

当应用程序恢复时,启动它:

_getBasketTimer = new Timer(getBasketCallback, null, 5000, Timeout.Infinite);

1
为什么不使用一个间隔为5秒的计时器,在其Tick事件中检查篮子? - Romasz
我不知道我可以做这样的事情 :) 但听起来很酷! - WPMed
@Romasz Task.Delay 内部会使用定时器。 - Yuval Itzchakov
@YuvalItzchakov 今天又是一个学习的好日子。我可以问你几个关于这个问题的问题吗?它会使用什么类型的计时器?它总是像这样工作吗? - Romasz
1
@Romasz 是的。这个链接会回答你的问题 :) - Yuval Itzchakov
1
@YuvalItzchakov 对于之前的评论我很抱歉,我错过了您评论中 This 后面的链接。现在一切都清楚了。 - Romasz
2个回答

2

没有看到更多的代码很难判断,不过你可能需要在一个新线程中包装你的循环以将其从UI线程中移除:

 Task.Run(async () =>
            {
               while(UserLoggedIn)
               {
                  await Networking.getBasket();
                  await Task.Delay(5000);
               }
            });

1

如果你想在一个线程上间隔地运行某个东西(也可以是UI线程以外的线程),你可以使用 System.Threading.Timer。一个示例可能如下所示:

System.Threading.Timer myTimer = new System.Threading.Timer(async (state) => { if (UserLoggedIn) await Task.Delay(1000); }, null, 0, 5 * 1000);

请注意,如果您想从计时器的回调函数中访问UI元素,则必须使用 Dispatcher 。
此外,在应用程序被挂起时,请不要忘记停止计时器/取消任务,并在恢复事件上恢复它们(如果仍然需要)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接