C#/XAML/Win 8 アプリケーションを継承しました。n 秒ごとに実行するように設定されているコードがあります。
それを設定するコードは次のとおりです。
if(!_syncThreadStarted)
{
await Task.Run(() => SyncToDatabase());
_syncThreadStarted = true;
}
上記のコードは 1 回実行されます。
そして、SyncToDatabase() 内には次のものがあります。
while (true)
{
DatabaseSyncer dbSyncer = new DatabaseSyncer();
await dbSyncer.DeserializeAndUpdate();
await Task.Delay(10); // after elapsed time re-run above code
}
メソッド DeserializeAndUpdate は、オブジェクトのメモリ内コレクションをクエリし、それらのオブジェクトを Web サービスにプッシュします。
場合によっては、Web サービスへの送信要求に予想よりも時間がかかり、重複したアイテムが送信されることがあります。
質問:メソッド SyncToDatabase() 内で停止/中止/破棄し、完了したら初期化/開始できるスレッドまたはスレッド プール/バックグラウンド ワーカーを使用する方法はありますか? これにより、前のリクエストがまだ保留中の間、後続のリクエストが起動されなくなります。
編集:スレッドに関してはあまり知識がありませんが、必要なロジックは次のとおりです。
x秒ごとに何らかのメソッドを実行するスレッドを作成し、そのスレッドが開始すると「x秒ごとに実行」部分を停止し、スレッドが完了したら「x秒ごとに実行」部分を再度開始します。
たとえば、スレッドが午前 10:01:30 に開始され、午前 10:01:39 (9 秒) まで完了しない場合、次のスレッドは午前 10:01:44 (作業完了後 5 秒) に開始する必要があります。これは意味がありますか? 同時に 2 つ以上のスレッドを実行したくありません。
上記のコードは次のとおりです。
var period = TimeSpan.FromSeconds(5);
var completed = true;
ThreadPoolTimer syncTimer = ThreadPoolTimer.CreatePeriodicTimer(async (source) =>
{
// stop further threads from starting (in case this work takes longer than var period)
syncTimer.Cancel();
DatabaseSyncer dbSyncer = new DatabaseSyncer();
await dbSyncer.DeserializeAndUpdate(); // makes webservices calls
Dispatcher.RunAsync(CoreDispatcerPriority.High, async () =>
{
// Update UI
}
completed = true;
}, period,
(source) =>
{
if(!completed)
{
syncTimer.Cancel(); // not sure if this is correct...
}
}
ありがとう、アンドリュー)