1

ジョブの詳細リストを取得し、WPF MVVM .Net 4 プロジェクトで実行しようとしている状態を共有しない長時間実行ジョブを取得しました。バックグラウンド スレッドで実行され、並列処理が可能であるため、Task Parallel Library が最適な選択肢のようです。RelayCommands にも MVVM-Light を使用するプロトタイプ アプリを作成しました。例の「aTplTest.7z」は、https: //skydrive.live.com/redir?resid=DA3E430C1A5F3B81!186&authkey=!AOOWYGbB_PToC5A にあります。

プロトタイプは、以下を除いてほとんど動作します (テストのためにフィボナッチ計算を実行するだけです)。

  1. ビューをダイアログとして表示し、長時間実行されるプロセスを自動的に開始するにはどうすればよいですか? (現時点での回避策は、ユーザーに [スタート] ボタンを押させることです。)
  2. ユーザーがビューを閉じて、現在のジョブ インスタンスをキャンセルするときにタスクが例外を作成しないようにするにはどうすればよいでしょうか?

(たとえば、ユーザーがビューのウィンドウを閉じるボタンを押すと、catch の Invoke メソッドによって別の例外が作成されます。)

    private bool CreateVouchers(int[] workList)
    {
        var loopOptions = new ParallelOptions();
        loopOptions.CancellationToken = TokenSource.Token;
        var success = false;
        try
        {
            Parallel.ForEach(workList, loopOptions, t => BuildVoucher(t));
            success = true;
        }
        catch (OperationCanceledException)
        {
            var scm = new Action(ShowCancellationMessage);
            Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, scm);
        }
        return success;
    }

この投稿とソースの例を更新して、解決策を示します。

4

2 に答える 2

1

長時間実行されるプロセスを自動的に開始するには、次の Window_Loaded ハンドラーを Window_Closing ハンドラーを定義したコード ビハインドに追加するだけです。

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    var viewModel = (VoucherBuilderViewModel)this.DataContext;
    viewModel.CancelCommand.Execute(null);
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    var viewModel = (VoucherBuilderViewModel)this.DataContext;
    viewModel.RunJob();
}

もちろん、イベント ハンドラーを XAML に登録することを忘れないでください。

<Window Closing="Window_Closing" Loaded="Window_Loaded">

ウィンドウを閉じるときに例外を取り除くには、次の null チェックを追加します。

catch (OperationCanceledException)
{
    if (Application.Current != null)
    {
        var scm = new Action(ShowCancellationMessage);
        Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, scm);
    }
}
于 2012-10-23T18:08:40.277 に答える
0

あなたが尋ねているすべての詳細について完全に確信しているわけではありませんが、両方の質問に対処することができます.

  1. ビューをダイアログとして表示: これはモーダル ダイアログですか? ビューが Window から派生している場合 (これは簡単すぎるため、そうではないと想定しています)、view.ShowDialog(); を呼び出すだけです。
    長時間実行されるプロセスを開始するには、OnLoaded にアタッチするか、コンストラクターで実行します。

  2. ループ オプションでキャンセル トークンを使用することを含む、ビューを閉じる方法を登録します。Build Voucher では、キャンセル トークンにキャンセルが要求されているかどうかを確認し、メッセージの生成を適切に停止してクリーンアップします。

これが役立つことを願っています。コメントを追加していただければ、より多くの光を当てることができるかもしれません。

于 2012-10-23T16:55:16.383 に答える