我的应用程序中有一个循环,它以下列方式遍历一组实体
foreach(var entity in mEntities)
{
entity.Update();
}
其中一些实体维护一个网络组件,该组件将调用 Azure 移动服务,以便将其状态更新到服务器。下面是一个例子:
public class TestEntity {
public int Index;
public int PropertyValue;
public async void Update()
{
Task.Run(() => {
MyAzureMobileServiceClient.Update(Index, PropertyValue);
});
}
}
UI 渲染由 Monogame 以更传统的游戏循环方式完成。虽然我不知道它的内部工作原理,但我相当确定它没有真正的单独线程来完成这项工作。实际上,这显示为每次调用此更新时 UI 冻结。
我希望能够在后台“顺利”运行它。在旧的 Windows 模型中,这可以通过启动一个可以处理它的新线程来轻松完成,但是我对 WinRT 中的线程处理不够了解,无法理解我的方法有什么问题。
有任何想法吗?
[更新]我也试过这个:
Task.Factory.StartNew(async () =>
{
while(true) {
await Task.Delay(1000);
MyAzureMobileServiceClient.Update(Index, PropertyValue);
}
});
每隔 1 秒,我就会像以前一样进行一次小冻结。
[更新 2] 我尝试了这个。我用标准的 HTTP 请求替换了 Azure 移动服务客户端调用,它运行得非常好;没有小冻结。当然它还没有到后端,但至少我可以通过手动完成整个事情来解决这个问题。然而,宁愿不这样做。
[更新 3] 这变得很奇怪。我意识到我简化了这个问题中的代码,以使其在上下文中保持一致。然而,这似乎已经消除了问题的真正根源。我尝试了以下事情:
- 我创建了一个 HTTP 请求并手动创建了该请求,在 Task.Run() 中调用它,它运行良好,没有延迟。
- 我直接调用了 Azure 移动服务客户端更新,没有延迟。
所以这把我带到了问题所在。我基本上有一个 Azure 移动服务的包装类。真正的路径大致是这样的:
CommunicationClient.UpdateAsync(myObject);
public Task UpdateAsync(MyObjectType obj)
{
var table = mMobileServiceClient.GetTable<MyObjectType>();
return table.UpdateAsync(obj);
}
这会导致滞后,但如果我这样做而不是它,它不会有任何延迟:
var client = CommunicationClient.MobileServiceClient;
var table = client.GetTable<MyObjectType>();
table.UpdateAsync(obj);
太好了……我可能应该重构整个问题。它越来越干了。