Windows Phone 8.1 应用中的后台线程
Background thread in Windows Phone 8.1 app
我正在开发 Windows Phone 8.1 购物应用程序。我在应用程序中有一个连续的 运行ning 线程,它下载用户购物篮并将其保存在本地缓存中以提高性能。
到目前为止,我所拥有的是这样的:
while(UserLoggedIn)
{
await Networking.getBasket();
await Task.Delay(5000);
}
该线程在应用恢复时启动。我的问题是:控制这样一个线程的最佳方法是什么?在应用程序恢复时它看起来真的很慢,有时它会阻塞 UI 线程,尽管它是完全异步的。我怎样才能提高性能?
编辑
根据 Romasz 的建议,我使用了这样的 Timer:
正在声明:
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)
{
}
}
在App的Suspending事件中处理,所以当App挂起时Thread不会运行:
_getBasketTimer.Dispose();
并在应用恢复时启动它:
_getBasketTimer = new Timer(getBasketCallback, null, 5000, Timeout.Infinite);
如果不看更多代码就很难判断,但您可能需要将循环包装在一个新线程中以使其脱离 UI 线程:
Task.Run(async () =>
{
while(UserLoggedIn)
{
await Networking.getBasket();
await Task.Delay(5000);
}
});
如果你想 运行 间隔地在一个线程上做一些事情(也在 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.
此外,不要忘记在您的应用暂停后停止 timers/cancel 任务,并在恢复事件中恢复它们(如果仍然需要)。
我正在开发 Windows Phone 8.1 购物应用程序。我在应用程序中有一个连续的 运行ning 线程,它下载用户购物篮并将其保存在本地缓存中以提高性能。 到目前为止,我所拥有的是这样的:
while(UserLoggedIn)
{
await Networking.getBasket();
await Task.Delay(5000);
}
该线程在应用恢复时启动。我的问题是:控制这样一个线程的最佳方法是什么?在应用程序恢复时它看起来真的很慢,有时它会阻塞 UI 线程,尽管它是完全异步的。我怎样才能提高性能?
编辑
根据 Romasz 的建议,我使用了这样的 Timer:
正在声明:
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)
{
}
}
在App的Suspending事件中处理,所以当App挂起时Thread不会运行:
_getBasketTimer.Dispose();
并在应用恢复时启动它:
_getBasketTimer = new Timer(getBasketCallback, null, 5000, Timeout.Infinite);
如果不看更多代码就很难判断,但您可能需要将循环包装在一个新线程中以使其脱离 UI 线程:
Task.Run(async () =>
{
while(UserLoggedIn)
{
await Networking.getBasket();
await Task.Delay(5000);
}
});
如果你想 运行 间隔地在一个线程上做一些事情(也在 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.
此外,不要忘记在您的应用暂停后停止 timers/cancel 任务,并在恢复事件中恢复它们(如果仍然需要)。