次の方法で一連のエンティティをループするアプリケーションにループがあります
foreach(var entity in mEntities)
{
entity.Update();
}
これらのエンティティの一部は、状態をサーバーに更新するために Azure Mobile Service を呼び出すネットワーク コンポーネントを保持しています。以下に例を示します。
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】ひねりを加えてみました。Azure Mobile Service クライアントの呼び出しを標準の HTTP 要求に置き換えたところ、見事に機能しました。ミニフリーズはありません。バックエンドにはまだ対応していないことは確かですが、少なくとも、すべてを手動で行うことで回避策があります。ただし、そうしないことをお勧めします。
【追記3】おかしくなってきました。コンテキストで一貫性を持たせるために、この質問のコードを単純化したことに気付きました。ただし、これにより、問題の真の原因が取り除かれているようです。私は次のことを試しました:
- HTTP リクエストを作成し、リクエストを手動で作成し、それを Task.Run() 内で呼び出すと、レイテンシーなしで見事に機能しました。
- Azure Mobile Service クライアントの Update を直接呼び出したところ、待ち時間はありませんでした。
したがって、これは問題がどこにあるかに私をもたらします。基本的に、Azure Mobile Service のラッパー クラスがあります。進む実際のパスは、おおよそ次のようになります。
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);
すっごく...私はおそらく質問全体をリファクタリングする必要があります。乾いてきました。