1

ユーザーがボタンをクリックしたときにのみポップアップするキャンセルボタンのあるモーダルダイアログがあります。モーダルダイアログがポップアップした後、外部イベントを監視する長いプロセスを開始したいと思います。イベントが発生すると、ダイアログは自動的に閉じられます。ユーザーは、キャンセルボタンをクリックして、監視プロセスをキャンセルできます。

プロセス開始をShownイベントに割り当てました

private void ProceedForm_Shown(object sender, System.EventArgs e)
{
    controller.StartSwiping();
}

プロセス自体はループです

public void StartSwiping()
{           
    Status status;
    do
    {
        status = CallForFeedback();
    } while (status == Status.Pending);           

    form.DialogResult = DialogResult.OK;
    form.Close();
}

プロセスは正常に開始されますが、ダイアログがポップアップしないため、ユーザーはプロセスをキャンセルできません。また、開始をLoadイベントに割り当てようとしましたが、何も変更されませんでした。ダイアログを表示し、その後プロセスを開始する方法はありますか?

ありがとう

4

4 に答える 4

4

問題は、UIスレッドですべてを実行していることです。UIスレッドの応答性を維持できるように、ステータス監視ループを別のスレッドに配置する必要があります。

これを行うにはいくつかの方法がありますが、簡単に開始できる場所の1つは、BackgroundWorkerクラスを使用することです。

于 2012-07-25T14:50:55.233 に答える
1

を使用TaskしてLongRunningイベントを実行します。

CancellationTokenSource _cancelationTokenSource = new CancellationTokenSource();
new Task(() => 
{ 
  //Do LongRunning task
}, _cancelationTokenSource.Token, TaskCreationOptions.LongRunning).Start();

必要に応じて、を使用し_cancelationTokenSourceてタスクをキャンセルします。

于 2012-07-25T14:53:03.567 に答える
1

UIスレッドをブロックしているので、長時間実行されているコードをバックグラウンドスレッドに移動します。これが、UIが表示されない理由です。

コントローラ機能にバックグラウンドワーカークラスを使用するhttp://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

バックグラウンドワーカーで作業が完了すると(つまり、イベントが受信されると)、次のメカニズムを使用してUIスレッドにコールバックできます。

http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx

注:この記事では、クロススレッド例外をオフにできると述べていますが、これは悪い習慣と見なされます。代わりに、InvokeRequiredチェックを使用して正しい方法で処理し、Windowsフォームでメソッドを呼び出します。

于 2012-07-25T14:54:42.283 に答える
1

他の人は、BackgroundWorkerまたは他の種類のバックグラウンドスレッドを使用することを提案しています。多くの場合、これはここでは適切ですが、さらに優れた解決策がある可能性があります。長時間実行するタスクを実行しているだけでなく、何かが発生するのを待っています。常にポーリングするのではなく...それが何であれ、イベントを使用する必要があります。完了時にトリガーされるイベントがあり、正しい条件が満たされたときに必要なことをすべて実行する(つまり、ダイアログを閉じる)ために、そのイベントをサブスクライブする必要があります。

于 2012-07-25T15:03:14.717 に答える