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

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

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

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

非同期処理

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

WPF

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

Q&A

解決済

3回答

1613閲覧

WPFでの非同期処理について

inune

総合スコア13

C#

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

非同期処理

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

WPF

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

0グッド

0クリップ

投稿2019/02/04 15:04

WPFでの非同期処理について勉強しております。
いろいろ調べてみた結果非同期自体の処理はできましたが、なぜ動いているのか理解できませんでした。

理解している点として
・ボタンクリック時の関数にasyncをつけることで非同期での処理ができる
・この関数自体はUIスレッドで動いており、新しくタスクを生成すると別スレッドで動く
は理解しました。

ですがこの関数はUIスレッドで動いているため
タスクが終了するまでUIスレッドが止まる気がします。

私の中ではUIが固まり操作できなくなると思っているのですが
とくに固まることなく動いているのが疑問です。
理解が間違っているのでしょうか?

試したこと

実際同じスレッドか確かめるため非同期用の関数と普通のクリック関数でスレッドIDを出力
→同じIDだった

同時にUIの操作ができるか確かめるためそれぞれの関数からTextBoxを操作
→非同期の関数がUIを更新していても、別関数から操作可能

ソースコード

xaml

1<TextBox x:Name="text" HorizontalAlignment="Left" Height="224" Margin="10,35,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="272"/> 2<Button Content="Button1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click1"/> 3<Button Content="Button2" HorizontalAlignment="Left" Margin="92,10,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click2"/>

C#

1private async void Button_Click1(object sender, RoutedEventArgs e) 2{ 3 while (true) { 4 await Task.Delay(1); 5 text.AppendText("buttonClick1\n"); 6 Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: ButtonClick1"); 7 } 8} 9 10private void Button_Click2(object sender, RoutedEventArgs e) 11{ 12 text.AppendText("buttonClick2\n"); 13 Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: ButtonClick2"); 14}

また上記のソースコードでButton_Click1関数内で
awaitの行をコメントアウトすると完全にUIが固まってしまう理由も知りたいです。

補足情報(FW/ツールのバージョンなど)

Visual Studio Community 2017を使用

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

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

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

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

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

guest

回答3

0

一つのスレッドは一度に一つの処理しかできません
なので、時間のかかる処理をしながらUIを動かすというのは無理です
UIを動かしている間は他の処理ができないし、他の処理をしている間はUIは動きません。

それを避けるため、いくつもスレッドを生成して並行して処理をさせようという話になってます

投稿2019/02/04 22:04

編集2019/02/04 22:06
y_waiwai

総合スコア87749

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

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

inune

2019/02/05 01:12

UIを止めないために別スレッドで並行して処理をさせるのは理解できています。 async/awaitの挙動が気になっていたのですが、質問がわかりづらくすみませんでした。
guest

0

この関数自体はUIスレッドで動いており、新しくタスクを生成すると別スレッドで動く

ここのところに限った回答です。
質問の例で言うと別スレッドで動く新しいタスクはTask.Delayです。従ってボタンのハンドラでスレッドidをとってもUIのidが帰るのは当然です。
ボタンのハンドラはまさに非同期で別スレッドにディレイのタスクを投げたらすぐ復帰するので固まらない。awaitをやめるとディレイの戻りを待つので固まる。

投稿2019/02/05 00:26

papinianus

総合スコア12705

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

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

0

ベストアンサー

await は、そこでスレッドを停止して次の処理を呼ぶのを待てという命令ではありません。処理を停止して再度呼ばれるのを待てという命令です。

不正確ですが、await Task Delay(1) は、そこで一度 return し、1ms 後にまた元の状態を回復して続きから始めるに近いものだと思ってください。

例えば yield return のようなものとイメージしてみれば良いかもしれません。yield return は非同期ではありませんが、そこで処理が一度中断されて呼び出し元に戻るという点では似ています。

投稿2019/02/04 23:08

編集2019/02/04 23:21
Zuishin

総合スコア28660

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問