-1

バックグラウンドで操作を実行するためにUIスレッドと別のスレッドを使用し、それらの操作の結果でUIを更新するアプリがあります。

これはすべてうまくいきます。ただし、1 つの操作中に、ユーザーに何らかの値を入力するように求める必要があります。順序:

  • 実行中の UI スレッド
  • コマンド -> バックグラウンドで動作する 2 番目のスレッドが開始されました (作業スレッドと呼びましょう)
  • 作業スレッドは、操作を順番に実行しながらステータス情報を UI に送信します
  • ある特定の操作中に、作業スレッドが停止します
  • ユーザーがオプションを選択するには、ビューを表示する必要があるというメッセージが送信されます
  • UI スレッドはこのタイプのメッセージを購読しているため、ビューを表示します
  • ユーザーが選択を完了し、ビューを閉じる
  • 作業スレッドがユーザーの選択を受け取り、実行を続行します
  • 作業スレッドの終了

新しいスレッドを開始するコード:

Thread thread = new Thread(Convert);
thread.SetApartmentState(ApartmentState.STA); // avoid "The calling thread must be STA" exception
thread.Start();

作業スレッドから UI スレッドにステータス情報を送信するコード:

Application.Current.Dispatcher.BeginInvoke(
    System.Windows.Threading.DispatcherPriority.Normal,
    (Action<OperationStatus>)delegate(OperationStatus operation)
        {
            OperationList.Add(operation);
        }, status);

ユーザーに確認を求めるコード:

MainViewModel では、作業スレッドの実行中に:

// create ViewModel, that will be used as DataContext for dialog view
var vm = new SelectOptionViewModel(OptionList);
// subscribe to Close event, to get user selection
vm.Close += (s, e) =>
{
    _option = vm.SelectedOption;
};

AppMessages.DialogScreen.Send(vm);

MainView では、作業スレッドの実行中に:

AppMessages.DialogScreen.Register(this, vm =>
    {
        SelectOptionView view = new SelectOptionView();
        view.DataContext = vm;
        // view.Owner = this; // raises exeption about cross-threading
        view.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
        view.ShowDialog();
    });

問題は、ダイアログ ビューを親ビュー (MainView) の中央に表示するように設定する方法です。「this」は UI スレッドで作成されるため、view.Owner を「this」に設定することはできません。

定義されたシーケンスの順序を維持しながら、アプリでダイアログ ビューを中央に配置するには、ここで何を変更する必要がありますか?

4

2 に答える 2

1

バックグラウンドワーカーの使用を検討しましたか?

于 2012-08-31T18:26:12.097 に答える
0

ダイアログが作成される登録されたlabdaを実行するスレッドはどれですか?

UI スレッドである必要があります。

UI コンテキストでコードを実行し、結果を作業スレッドに戻す場合は、SynchronizationContext と Task を使用できます。

こちらの例をご覧ください。

于 2012-09-01T06:49:11.703 に答える