Windows Phone 7 アプリケーションで非同期ではないサーバー メソッドを使用する方法はありますか? データのリストがあります。foreach ループで、データごとにサーバーにリクエストを送信しますが、呼び出した順に完了しません。どうやってやるの?
2 に答える
データのリストがあります。foreach ループで、データごとにサーバーにリクエストを送信しますが、呼び出した順に完了しません。どうやってやるの?
それらを効果的に同期させることができます-実際のforeach ループを取り除き、代わりに適切な非同期コールバックを設定して、最初の応答が届いたときに2番目の要求を送信するなど、要求がなくなるまで. (a を使用してQueue<T>
、送信する要求をキューに入れることができます。)
何かが機能していないように見えるという理由だけで、同期方法に戻らないでください。非同期の世界で作業することには多くの利点があります。いくつかの危険もあります。重要なのは、それらの危険を回避する方法を知ることです。これは、有害な影響を与える WebClient を使用した例です。
foreach (var item in items)
{
WebClient client = new WebClient();
client.DownloadStringCompleted += (sender, args) =>
{
item.Stuff = args.Result;
};
client.OpenReadAsync(new Uri("http://mydomain.com/stuff"));
}
クライアントが返されたとき、それがitem
クライアント要求を「作成」したのと同じアイテムであるという保証はありません。これは「変更されたクローザーへのアクセス」として知られています。これは単に、もう存在しない、または同じではないものを変更しようとしている可能性があることを意味します。これに対する適切なアプローチは、次のように foreach 内でアイテムをキャプチャすることです。
foreach (var item in items)
{
var internalItem = item;
WebClient client = new WebClient();
client.DownloadStringCompleted += (sender, args) =>
{
internalItem.Stuff = args.Result;
};
client.OpenReadAsync(new Uri("http://mydomain.com/stuff"));
}
これにより、foreach のスコープ内でキャプチャされているため、正しいアイテムを使用していることを確認できます。