回答編集履歴

3

追記

2022/06/09 03:29

投稿

退会済みユーザー
test CHANGED
@@ -19,3 +19,70 @@
19
19
  async (C# リファレンス)
20
20
  https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/async
21
21
 
22
+ ---
23
+
24
+ **【追記】**
25
+
26
+ > 非同期に切り替えている
27
+
28
+ そこのところが疑問の原点になっているような気がします。スレッドがどのように使われているかを、メソッドを呼び出したらその中で Thread.CurrentThread.ManagedThreadId を調べるとそのあたりの疑問が解けるのではないかと思います。
29
+
30
+ 具体的には、例えば以下の Windows Forms アプリで、
31
+
32
+ ```
33
+ namespace WinFormsApp2
34
+ {
35
+ public partial class Form2 : Form
36
+ {
37
+ public Form2()
38
+ {
39
+ InitializeComponent();
40
+ }
41
+
42
+ // 非同期メソッド TimeCosumingMethod1 を呼び出す
43
+ private async void button1_Click(object sender, EventArgs e)
44
+ {
45
+ label1.Text = $"メインスレッド ID: {Thread.CurrentThread.ManagedThreadId}, IsBackground: {Thread.CurrentThread.IsBackground} / ";
46
+ label2.Text = "";
47
+ label2.Text = await TimeCosumingMethod1();
48
+ label1.Text += $"{Thread.CurrentThread.ManagedThreadId}, {Thread.CurrentThread.IsBackground}";
49
+
50
+ }
51
+
52
+ // 同期メソッド TimeCosumingMethod2 を呼び出す
53
+ private async void button2_Click(object sender, EventArgs e)
54
+ {
55
+ label1.Text = $"メインスレッド ID: {Thread.CurrentThread.ManagedThreadId}, IsBackground: {Thread.CurrentThread.IsBackground} / ";
56
+ label2.Text = "";
57
+ label2.Text = await Task.Run(() => TimeCosumingMethod2());
58
+ label1.Text += $"{Thread.CurrentThread.ManagedThreadId}, {Thread.CurrentThread.IsBackground}";
59
+ }
60
+
61
+ // 非同期メソッド
62
+ private async Task<string> TimeCosumingMethod1()
63
+ {
64
+ string s = $"TimeCosumingMethod1 スレッド ID: {Thread.CurrentThread.ManagedThreadId}, IsBackground: {Thread.CurrentThread.IsBackground} IN / ";
65
+ await Task.Delay(3000);
66
+ return s + $"{Thread.CurrentThread.ManagedThreadId}, {Thread.CurrentThread.IsBackground} OUT";
67
+ }
68
+
69
+ // 同期メソッド
70
+ private string TimeCosumingMethod2()
71
+ {
72
+ string s = $"TimeCosumingMethod2 スレッド ID: {Thread.CurrentThread.ManagedThreadId}, IsBackground: {Thread.CurrentThread.IsBackground} IN / ";
73
+ Thread.Sleep(3000);
74
+ return s + $"{Thread.CurrentThread.ManagedThreadId}, {Thread.CurrentThread.IsBackground} OUT";
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ 非同期メソッド TimeCosumingMethod1 を呼び出した場合、下の画像にある通り ManagedThreadId は全て 1 で UI スレッドになっています。
81
+
82
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-06-09/9b1c9d53-b1bf-4ea4-8640-3556c35980c3.jpeg)
83
+
84
+ 同期メソッド TimeCosumingMethod2 を Task.Run を使って呼び出した場合は、TimeCosumingMethod2 がスレッドプールから別スレッドを取得して実行されるので、下の画像の通りManagedThreadId が異なります(7 になっています)。
85
+
86
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-06-09/80cb840b-7a9f-446f-89fa-272797bdf512.jpeg)
87
+
88
+ 「非同期に切り替えている」ということではないのが分かるでしょうか?

2

強調追加

2022/06/09 01:58

投稿

退会済みユーザー
test CHANGED
@@ -1,4 +1,4 @@
1
- **ボールドテキスト**参考にしている記事は長いし、質問者さんのコードもよく分からないので、表題に対してのみレスします。
1
+ 参考にしている記事は長いし、質問者さんのコードもよく分からないので、表題に対してのみレスします。
2
2
 
3
3
  > Task.Runを使用せずにasync-awaitだけで非同期処理を実現できるのか
4
4
 

1

強調追加

2022/06/09 01:57

投稿

退会済みユーザー
test CHANGED
@@ -1,4 +1,4 @@
1
- 参考にしている記事は長いし、質問者さんのコードもよく分からないので、表題に対してのみレスします。
1
+ **ボールドテキスト**参考にしている記事は長いし、質問者さんのコードもよく分からないので、表題に対してのみレスします。
2
2
 
3
3
  > Task.Runを使用せずにasync-awaitだけで非同期処理を実現できるのか
4
4
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  ちなみに、async をメソッドに付与して内部で await を使わないと以下の警告が出ますよね。
8
8
 
9
- warning CS1998: この非同期メソッドには 'await' 演算子がないため、同期的に実行されます。'await' 演算子を使用して非ブロッキング API 呼び出しを待機するか、'await Task.Run(...)' を使用してバックグラウンドのスレッドに対して CPU 主体の処理を実行することを検討してください。
9
+ warning CS1998: この非同期メソッドには 'await' 演算子がないため、同期的に実行されます。'await' 演算子を使用して非ブロッキング API 呼び出しを待機するか、**'await Task.Run(...)' を使用して**バックグラウンドのスレッドに対して CPU 主体の処理を実行することを検討してください。
10
10
 
11
11
  .NET Frameworkにおける非同期処理実装技術の歴史は以下の記事の Figure 3 のようになっているそうです。そういう経緯から勘違い(?)して、Task はもう使わないとかいう記事を目にしますが、それはちょっと違うと思います。
12
12