1

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 が呼び出されないためです。

4

1 に答える 1

2

問題は、timerTick メソッドを呼び出したからといって、Backgroundworker がビジーではないことです。したがって、メソッドの残りの部分が実行される前にこのコードに到達することはなく、フォームが閉じられてアプリケーションが閉じます。

    while (PublishBackgroundWorker.IsBusy)
        System.Threading.Thread.Sleep(100);
于 2013-04-10T19:17:48.137 に答える