Web サービス呼び出しを介して、保存されていないデータを外部 DB に保存する必要があるフォームがあります。ユーザーが手動でデータを保存すると、RunWorkerCompleted がトリガーされますが、FormClosing イベントを介してメソッドを呼び出すとトリガーされません。
ユーザーがフォームの値を変更してから数秒後にタイマーが作動し、ユーザーが別の値を変更するとリセットされます。これは、「toSend」リストに複数の値があり、一度に複数の変更を公開できるという考えです。 Web サービスの呼び出しはオーバーヘッドが大きいためです。
private void timer1_Tick(object sender, EventArgs e)
{
if (PublishBackgroundWorker.IsBusy)
return;
List<object> toSend = new List<object>();
// Figure out what changed and add it to toSend ...
toSend.Add(changedItems);
if (toSend.Count >= 1)
PublishBackgroundWorker.RunWorkerAsync(toSend);
}
private void PublishBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (((List<object>)(e.Argument)).Count > 0)
{
Service.SrvObjects[] ret = Svc.PublishItems(e.Argument));
}
}
private void PublishBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { "Ready" });
}
private void IPTUserInterfaceForm_FormClosing(object sender, FormClosingEventArgs e)
{
timer1.Enabled = false;
timer1_Tick(this, new EventArgs());
//Application.DoEvents();
while (PublishBackgroundWorker.IsBusy)
System.Threading.Thread.Sleep(100);
}
これは理にかなっていますか?ユーザーが値を変更し、タイマーが切れる前にフォームを閉じると、PublishBackgroundWorker.IsBusy がある時点で false になることを期待して手動で Tick します。RunWorkerCompleted が呼び出されないためです。