質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

3回答

5042閲覧

WPF: 非同期にProcessの終了をチェックする

5REva

総合スコア15

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

1クリップ

投稿2018/12/12 15:15

編集2018/12/31 02:06

WPFで非同期にProcessの終了を取りたいです。概要、以下のようなコードです。

Formではなく、WPFだと、上手く動かないように思います。Dispatcherとかが関係しているのでしょうか。不勉強なところ、大変恐縮ですが、ご教示頂けますと幸いです。

//some_project.xaml <UserControl:ToggleSwitch x:Name="SomeControl" Checked="ToggleSwitch_Checked"/> <MediaElement x:Name="LoadingIcon"/> //some_project.xaml.cs private void LoadingStart(){ //LoadingIconの開始処理 } private void LoadingFinish(){ //LoadingIconの終了処理 } private void ToggleSwitch_Checked(object sender, RoutedEventArgs e){ var process = new Process() Directory.SetCurrentDirectory(directory_path); process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; process.StartInfo.FileName = "cmd"; process.StartInfo.Arguments = string.Format("/c \"{0} < {1}\"", @"test.exe", test_input_file_path); process.EnableRaisingEvents = true; process.Exited += (sender, e) => { SomeControl.IsChecked = false; }; process.Start(); }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2018/12/12 21:36

どうなったらうまく動いたことになりますか?
5REva

2018/12/13 00:22

ありがとうございます。 ボタンをクリックすると、あるコントロールのチェックがtrueになり、上記のプロセスが動いて、上記プロセスが完了すると、そのコントロールのチェックがfalseになると、うまく動いた事になります。
Zuishin

2018/12/13 00:25

現在はどうなりますか?
5REva

2018/12/13 00:26

プロセスが終了しても、チェックがtrueのままです
Zuishin

2018/12/13 00:27

SomeControl.IsChecked = false; にブレークポイントを置くとそこで停止しますか?
5REva

2018/12/13 00:31

停止しません。
Zuishin

2018/12/13 00:36

ProcessStartInfo と Process が関連付けられていないようですが、Process のコンストラクタで渡すとどうなりますか?
5REva

2018/12/13 11:05

ありがとうございます。試してみます。
guest

回答3

0

自己解決

最終的に、Dispatcher.BeginInvokeを介入させる方法で、うまく動きました。こちらが参考になりました。
https://stackoverflow.com/questions/4821265/updating-parent-process-gui-on-receiving-process-exited-event-wpf

XAML

1some_project.xaml 2<UserControl:ToggleSwitch x:Name="SomeControl" Checked="ToggleSwitch_Checked"/> 3<MediaElement x:Name="LoadingIcon"/>

C#

1some_project.xaml.cs 2private void LoadingStart(){ 3 //LoadingIconの開始処理 4} 5 6private void LoadingFinish(){ 7 //LoadingIconの終了処理 8} 9 10private void ToggleSwitch_Checked(object sender, RoutedEventArgs e){ 11 LoadingStart(); 12 13 Directory.SetCurrentDirectory(directory_path); 14 Process process = new Process(); 15 process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 16 process.StartInfo.FileName = "cmd"; 17 process.StartInfo.Arguments = string.Format("/c \"{0} < {1}\"", @"test.exe", test_input_file_path); 18 19 process.Exited += process_Exited; 20 process.EnableRaisingEvents = true; 21 22 process.Start(); 23} 24 25private void process_Exited(object sender, EventArgs e){ 26 this.Dispatcher.BeginInvoke( 27 new Action(() => { 28 LoadingFinish(); 29 SomeControl.IsChecked = false; 30 })); 31}

投稿2018/12/31 02:09

5REva

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

ここでコマンドラインをあえて見えなくしていると思いますが、
表示してみて、cmdプロセスがしっかり終了している事を確認していますか?

投稿2018/12/13 02:11

takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

5REva

2018/12/13 11:06 編集

ありがとうございます。表示してみます。 WaitForExitで同期で止めて、SomeControl.IsChecked = falseとすると、ちゃんと動きます。他のメソッドの関係で、ここを非同期でやる必要があるのですが、うまく行きません。 StackOverFlowとかみると、Dispatcherを介しているみたいで、こっちも試したんですが、うまく行かず(正直、私があまりDispatcherをわかっていない気がしています。) https://stackoverflow.com/questions/4821265/updating-parent-process-gui-on-receiving-process-exited-event-wpf
takabosoft

2018/12/14 00:26

質問欄で「SomeControl.IsChecked = false;」箇所にブレークポイントを貼っても停止しないという回答がありますので、Dispatchar以前の問題かと思われます。他の方の回答(GCなど)の検証もお願いいたします。
5REva

2018/12/31 02:11

私の情報が不足してたように思います。情報を追加し、うまく動いたコードも共有させて頂きました。どうもありがとうございました。
guest

0

processの参照を残してなくて、GCに回収されちゃっているに一票入れときます。

追記:process又はイベントハンドラのどちらかをフィールドなどに保持しておいてください。

追記その2:↑と書きましたがイベントハンドラを保持するほうが確実ですね。
processの中身を知る必要がないので。

投稿2018/12/13 01:44

編集2018/12/13 02:11
hihijiji

総合スコア4152

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hihijiji

2018/12/14 03:25

別スレッドからコントロールを操作すると例外が発生します。例外が出ないならそれ以前の問題です。 イベントを発生するオブジェクトとそのイベントハンドラの両方の参照を捨てているならいつかはGCに回収されます。 Windows.Formsで同じようにして動いていたなら、それは偶々回収されずに動いていただけです。
5REva

2018/12/31 02:11

私の情報が不足してたように思います。情報を追加し、うまく動いたコードも共有させて頂きました。どうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問