回答編集履歴
2
大事なこと
answer
CHANGED
@@ -9,9 +9,9 @@
|
|
9
9
|
|
10
10
|
---
|
11
11
|
|
12
|
-
ちなみに、前回の質問のコメントで`tasks.
|
12
|
+
ちなみに、前回の質問のコメントで`tasks.ForEach(t=>t.Result);`としているのは、その手法をあえて採用する価値が全く無いことは置いといて、「その直前で`await Task.WhenAll(tasks.ToArray());`をしている場合は安全」です。何故かと言うと、`WhenAll`によって「`tasks`の全てのTaskが完全に完了していることが保証されている」からです。これの意味が完全に分かる頃には、どうして`.Result`を使ってはいけないか、どこに`.Result`を使っても安全か、も分かっているはずです。
|
13
13
|
|
14
|
-
以下に前回の質問のコードの重点を整理しました。**どちらでも同じ結果は得られる**ため、「**あえて推奨されないやり方を選ぶ理由があるならそうすれば良い**」というのが結論ですね。
|
14
|
+
以下に前回の質問のコードの重点を整理しました。**どちらでも同じ結果は得られる**ため、「**あえて推奨されないやり方を選ぶ理由があるならそうすれば良い**」というのが結論ですね。ただし、「`Task.WhenAll`を`await`しない」というのは論外です。
|
15
15
|
|
16
16
|
推奨されるやり方:
|
17
17
|
```csharp
|
@@ -24,4 +24,17 @@
|
|
24
24
|
```csharp
|
25
25
|
await Task.WhenAll(tasks.ToArray());
|
26
26
|
tasks.ForEach(x => x.Result);
|
27
|
+
```
|
28
|
+
|
29
|
+
|
30
|
+
論外、デッドロックが発生する可能性がある:
|
31
|
+
```csharp
|
32
|
+
var result = Task.WhenAll(tasks.ToArray());
|
33
|
+
tasks.ForEach(x => x.Result);
|
34
|
+
|
35
|
+
/*---------------------------------------*/
|
36
|
+
|
37
|
+
var result = Task.WhenAll(tasks.ToArray());
|
38
|
+
foreach (var r in result.Result)
|
39
|
+
Console.WriteLine(r);
|
27
40
|
```
|
1
追記
answer
CHANGED
@@ -7,4 +7,21 @@
|
|
7
7
|
実際、**限られた状況ではどちらでも同じ結果を得ることが可能**です。しかし、`.Result`では非同期のメリットが一切得られなくなるため、このシーンで採用する価値は皆無です。
|
8
8
|
さらに、`.Result`の手法には大きな問題があります。それは、「非同期コンテキストを無理に同期することになるため、デッドロックを引き起こす可能性がある」ことです。これはちょっとしたコードでも簡単に発生するので、「使っても絶対に安全な場面である」「何故安全であるか理解している」「その上で`.Result`を使うことに説得力がある理由が存在する」を全て満たす場合にのみ使ってください。つまりは、実質使用禁止ということです。
|
9
9
|
|
10
|
-
|
10
|
+
---
|
11
|
+
|
12
|
+
ちなみに、前回の質問のコメントで`tasks.foreach(t=>t.Result);`としているのは、その手法をあえて採用する価値が全く無いことは置いといて、「その直前で`await Task.WhenAll(tasks.ToArray());`をしている場合は安全」です。何故かと言うと、`WhenAll`によって「`tasks`の全てのTaskが完全に完了していることが保証されている」からです。これの意味が完全に分かる頃には、どうして`.Result`を使ってはいけないか、どこに`.Result`を使っても安全か、も分かっているはずです。
|
13
|
+
|
14
|
+
以下に前回の質問のコードの重点を整理しました。**どちらでも同じ結果は得られる**ため、「**あえて推奨されないやり方を選ぶ理由があるならそうすれば良い**」というのが結論ですね。
|
15
|
+
|
16
|
+
推奨されるやり方:
|
17
|
+
```csharp
|
18
|
+
var result = await Task.WhenAll(tasks.ToArray());
|
19
|
+
foreach (var x in result)
|
20
|
+
Console.WriteLine(x);
|
21
|
+
```
|
22
|
+
|
23
|
+
推奨されないやり方:
|
24
|
+
```csharp
|
25
|
+
await Task.WhenAll(tasks.ToArray());
|
26
|
+
tasks.ForEach(x => x.Result);
|
27
|
+
```
|