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

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

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

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

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

6792閲覧

[C#,C++]時間のかかる処理を行う際の待機カーソルを消したい

makiikeda1216

総合スコア128

C#

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

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2015/05/18 05:18

編集2015/05/18 08:06

現在、WindowsFormアプリを作成しています。その処理の中で約1秒ほどかかる外部のアプリを10~1000回ほど呼び出すのですがその際、待機カーソルが表示され、通常のカーソルと待機カーソルが交互にあわられチカチカしてしまっているので、常に通常カーソルが表示されている状態にしたいと思っています。

自分が調べたところによるとその待機カーソルが呼ばれる処理を行っている間メインスレッドで生成されたメッセージループが待機状態となり、待機カーソルが表示されるということがわかったのですが、どのように常にメッセージを処理し続ければいいのかわからずに困っています。

C#でApplication.DoEvent()という関数を使ってメッセージループをまわしてみたのですが、待機カーソルが少し表示されなくなりましたが常に通常カーソルが表示されるといった感じにはなりませんでした。

約1秒ほどの長い処理を何回も呼んでも常に通常カーソルを表示させるにはどのようにしたらようでしょうか?知っている方がいましたらご教授ください。

以下が外部アプリ(C++)を呼んだ際にDoEventをはさんだ処理です。

lang

1 2//FormLoadイベントAで下記メソッドを呼び出す 3private async void Form1_Load(object sender,EventArgs e) 4{ 5 await AsyncClient();//メソッドBの呼び出し 6} 7 8 9 10//外部アプリを10~1000回呼ぶメソッドB 11public async Task<int> AsyncClient() 12{ 13 //いろいろな処理(省略)... 14 15 while(dataReader.Read())//DBのレコード数分10~1000回くらまわします 16 { 17 await CallProcessMethod();//外部プロセスを呼ぶメソッド 18 } 19} 20 21 22//外部アプリを呼ぶメソッドC 23 24public static async Task<T> CallProcessMethod() 25{ 26var process_1 = new Process() 27 { 28 StartInfo = 29 { 30 FileName = "外部アプリ.exe", 31 Arguments = xxxxxxxx 32 } 33 }; 34 35 await Task.Factory.StartNew(() => 36 { 37 Application.DoEvents(); 38 }); 39 40 await Task.Factory.StartNew(() => process_1.Start()); 41 await Task.Factory.StartNew(() => process_1.WaitForExit());//約1秒ほどかかるC++の"外部アプリ.exe"をここで起動 42 await Task.Factory.StartNew(() => process_1.Dispose()); 43 44 await Task.Factory.StartNew(() => 45 { 46 Application.DoEvents(); 47 }); 48}

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

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

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

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

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

ozwk

2015/05/18 07:37

>外部のアプリを10~1000回ほど呼び出すのですが どうやって10~1000回呼んでいるのですか?
makiikeda1216

2015/05/18 07:55

別のクラスの非同期メソッドAでDBのレコード数分、外部アプリを呼ぶメソッドBを非同期で呼んでいます。この非同期メソッドAをFormLoad()で呼んで実行しています。外部アプリの呼んでいるメソッドは上記に書いていますがもう少し追記させていただきます! class Client{ public async Task<int> AsyncClient() { //省略.... while(dataReader.Read)//レコード数文まわしますここで10~1000回とかわります。 {   await callProcessMethod();//外部アプリを呼ぶメソッド } } }
makiikeda1216

2015/05/18 07:56

ここに書くと読みずらいので掲示板に追記しますOTL
guest

回答3

0

質問のコードを、1000回実行するものとして、簡略化するとこんな感じです。

lang

1private async void Form1_Load(object sender,EventArgs e) 2{ 3 for(int i=0;i<1000;i++) 4 { 5 var process_1 = new Process(){...}; 6 await Task.Run(()=>SuperHeavyFunc()); 7 } 8}

(Task.RunはTask.Factory.StartNewとほぼ一緒です。)
これだとUIスレッド上で、
・process_1を生成。
・重い処理を別スレッドにお願いする。
・(あと終了条件の確認とか省かれた諸々)
を1000回繰り返すことになります。

そこで、

lang

1private async void Form1_Load(object sender,EventArgs e) 2{ 3 await Task.Run(()=> 4 { 5 for(int i=0;i<1000;i++) 6 { 7 var process_1 = new Process(){...}; 8 SuperHeavyFunc(); 9 } 10 } 11}

とすれば、全部の処理をUIスレッド外に投げられます。

Application.DoEvents()は忘れましょう。

投稿2015/05/18 09:16

編集2015/05/18 09:20
ozwk

総合スコア13512

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

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

makiikeda1216

2015/05/19 00:41

回答ありがとうございます!調べてみましたがTask.Run()のほうが新しい機能なのですね!同じように書いてみたのですが、やはり待機カーソルが消えませんでした...外部アプリ.exeがUIのないMFCアプリケーションなのですが、もしかしてそのメインスレッドのメッセージループが待機状態だとしたらそもそも呼び出し側で待機カーソルを消すことができないというオチでしょうか。。
guest

0

自己解決

お騒がせしました。
原因がわかりました。

原因はMFCアプリケーションが起動し、初期化する際にメインスレッドが一瞬待機状態になり、
重い処理とは関係なく待機カーソルが表示されていました。

通常C#で非同期で起動すればやはりTask.Run()もTask.Factory.StartNew()も待機カーソルは表示されないっぽいですね。書き方によって動作が違うようですが。。

解決方法
UIのないコンソールアプリケーションを使用する。

質問に付き合っていただいた皆様、どうもありがとうございましたOTL

投稿2015/05/22 00:26

makiikeda1216

総合スコア128

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

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

0

投稿2015/05/18 09:15

cateye

総合スコア6851

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

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

makiikeda1216

2015/05/19 01:10

回答ありがとうございます!カーソルをプロパティーから直接変更はすでに試していたのですが。やはり無理でした。待機カーソルに変更されるのはWindowsのメッセージループの仕様?みたいなのでそこの処理をどうにかしてあげないとだめなようです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問