・メソッド内で非同期処理を呼んで、その戻り値を取得したい。
C#、.NetFramework4.0で開発しています。
ある処理の中で非同期処理を呼んで、その戻り値を取得したいです。
また、非同期処理が終了するまで呼び元の処理を待たせたいです。
非同期処理の中である値を取得するのですが、
その値を受け取った時点で非同期処理自体は終了し、
それが終わったことを呼び元の処理が判断できればと考えています。
非同期なのに、待つというのも変なのですが、
Thread.Sleepを使って待たせると、
呼び元が固まってしまうのを
回避したいため非同期処理を使用しています。
実際には下記の様な流れになります。
①メインフォーム→②あるクラスのメソッドを呼び出す。→③非同期処理を呼ぶ。
ご教授よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/01 07:32

回答5件
0
下記のサイトが参考になるかと。
投稿2018/08/01 07:56
総合スコア3581
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
Task.Wait メソッド()で処理をウェイトしてあげると良いと思います
4.0で使えます。
使い方としてはざっくりと以下のような感じ
C#
1using System; 2using System.Threading.Tasks; 3 4public class Example 5{ 6 public static void Main() 7 { 8 //非同期処理をTaskでやる 9 Task t = Task.Run( () => { 10 Console.WriteLine("非同期処理だよ"); 11 } ); 12 //処理が終わるまでWaitのところでブロッキングする 13 t.Wait(); 14 } 15}
#追記(2018/08/04)
######フォームが固まる理由について
Waitを呼んだ処理がメインスレッドとして動いているのだと思います。
画面の描画やユーザーの操作を受け取ったりするのはメインスレッドだけです。
なので、もしメインスレッドをWaitしてしまった場合は画面が固まります。
=メインスレッドでSleepもWaitもしないこと
######フォームが固まらないようにする方法
フォームが止まらないように直すのであれば、
ある変数の値が変わるまで待つ処理
この処理自体はメインスレッド以外のスレッドでやるべきです。
つまりメインスレッドは処理を続行し非同期処理用のスレッドを2つ作成する必要があります。
コードを添付します。
コメント文の「★」は後述の問題点です。
C#
1private void button1_Click(object sender, EventArgs e) 2{ 3 //ここでSleepしたらメインスレッドがSleepするので、画面が固まる 4 //Thread.Sleep(100);などしない 5 //ある変数の値が変わるまで待つ処理 6 Task taskForWait = Task.Run( () => { 7 Task t= Task.Run( () => { 8 //やりたい処理 9 } ); 10 11 t.Wait(); 12 //★どう通知するの?taskForWaitがtの終わりを知れればOK? 13 } ); 14 //★ここで値を受け取ったことを判断する処理を呼び出すと画面固まるので非同期処理の意味がない 15} 16
######上記コードの問題点
この実装だとメインスレッドはスレッドに処理を任せているだけなので
もし値を受け取ったことを判断する処理を呼び元(メインスレッド上)に作ってしまうと
非同期処理の意味がなくなってしまいます。
必ずしもタイマー処理で値を受け取ったことを判断する必要はあるのでしょうか。
例えば、値を受け取ったらイベントとして送ってあげて、
別で処理してあげる…とか色々方法はあると思います。
とにかく、現在の質問者様の意図を組み取る限りでは実装が難しいように思います。
何か誤解がありましたら教えてください。
投稿2018/08/02 07:33
編集2018/08/03 21:32総合スコア2663
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
4.0 なので await は使えないとコメントされていたので。
開発環境が VS2012 以降であれば、ライブラリを参照すれば 4.0 でも await できますよ。
非同期メソッド入門 (12) - .NET Framework 4.5以外でawaitする
投稿2018/08/01 22:10
総合スコア449
0
Task処理は悩ましいもので、先日もしっかり、固まりました。
以下の方法はどうでしょうか?
Task t1 = new Task(Exec1);
t1.Start();
実際の実行メソッド (Exec1) の最後に、自分自身のメソッドを呼び出す。
ただし、BeginInvoke()を使って。
これならば、.NetFramework4.0 でもOKだと思います。
Timer処理ならば、Timerを Killする(Dispose?) もありかと。
投稿2018/08/01 11:29
総合スコア6385
0
非同期処理の終了時に実行するデリゲートを設定して、それでフォームに対してなにかをするとか
あるいはその待つ処理そのものを非同期処理にしてしまうとか
投稿2018/08/01 07:23
総合スコア88180
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。