Language
Note
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãµã€ã³ã€ã³ãŸãã¯ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ã¿ã¹ã¯äžŠåã©ã€ãã©ãª (TPL) ã¯ãéåææäœã衚ã ã¿ã¹ã¯ã®æŠå¿µã«åºã¥ããŠããŸãã ããæå³ã§ã¯ãã¿ã¹ã¯ã¯ã¹ã¬ããã ThreadPool äœæ¥é ç®ã«äŒŒãŠããŸãããæœè±¡åã®ã¬ãã«ã¯é«ããªããŸãã ã¿ã¹ã¯ã®äžŠååŠç ãšããçšèªã¯ãåæã«å®è¡ããã 1 ã€ä»¥äžã®ç¬ç«ããã¿ã¹ã¯ãæããŸãã ã¿ã¹ã¯ã«ã¯ã次㮠2 ã€ã®äž»ãªå©ç¹ããããŸãã
ã·ã¹ãã ãªãœãŒã¹ã®ããå¹ççã§ã¹ã±ãŒã©ãã«ãªäœ¿çšã
ããã¯ã°ã©ãŠã³ãã§ã¯ãã¿ã¹ã¯ã¯ ThreadPoolã«ãã¥ãŒã«å ¥ããããŸããããã¯ãã¹ã¬ããã®æ°ã決å®ããŠèª¿æŽããã¢ã«ãŽãªãºã ã«ãã£ãŠåŒ·åãããŠããŸãã ãããã®ã¢ã«ãŽãªãºã ã¯ãã¹ã«ãŒããããæå€§åããããã®è² è·åæ£ãæäŸããŸãã ãã®ããã»ã¹ã«ãããã¿ã¹ã¯ã¯æ¯èŒç軜éã«ãªãããã®å€ããäœæããŠãã现ãã䞊ååŠçãå¯èœã«ããããšãã§ããŸãã
ã¹ã¬ãããŸãã¯äœæ¥é ç®ã§å¯èœãªãããå€ãã®ããã°ã©ã ã«ããå¶åŸ¡ã
ã¿ã¹ã¯ãšãã®åšå²ã«æ§ç¯ããããã¬ãŒã ã¯ãŒã¯ã¯ãåŸ æ©ããã£ã³ã»ã«ãç¶ç¶ãå ç¢ãªäŸå€åŠçã詳现ãªç¶æ ãã«ã¹ã¿ã ã¹ã±ãžã¥ãŒã«ãªã©ããµããŒãããè±å¯ãª API ã»ãããæäŸããŸãã
ã©ã¡ãã®çç±ã§ããTPL ã¯ã.NET ã§ãã«ãã¹ã¬ãããéåæãããã³äžŠåã³ãŒããèšè¿°ããå Žåã«æšå¥šããã API ã§ãã
ã¿ã¹ã¯ã®æé»çãªäœæãšå®è¡
Parallel.Invoke ã¡ãœããã¯ãä»»æã®æ°ã®ã¹ããŒãã¡ã³ããåæã«å®è¡ãã䟿å©ãªæ¹æ³ãæäŸããŸãã äœæ¥é
ç®ããšã« Action ããªã²ãŒããæž¡ãã ãã§ãã ãããã®ããªã²ãŒããäœæããæãç°¡åãªæ¹æ³ã¯ãã©ã ãåŒã䜿çšããæ¹æ³ã§ãã ã©ã ãåŒã¯ãååä»ãã¡ãœãããåŒã³åºãããã³ãŒããã€ã³ã©ã€ã³ã§æäŸã§ããŸãã æ¬¡ã®äŸã¯ãåæã«å®è¡ããã 2 ã€ã®ã¿ã¹ã¯ãäœæããŠéå§ããåºæ¬ç㪠Invoke åŒã³åºãã瀺ããŠããŸãã æåã®ã¿ã¹ã¯ã¯ãDoSomeWorkãšããååã®ã¡ãœãããåŒã³åºãã©ã ãåŒã§è¡šããã2 çªç®ã®ã¿ã¹ã¯ã¯ãDoSomeOtherWorkãšããååã®ã¡ãœãããåŒã³åºãã©ã ãåŒã«ãã£ãŠè¡šãããŸãã
æèš
ãã®ããã¥ã¡ã³ãã§ã¯ãã©ã ãåŒã䜿çšã㊠TPL ã§ããªã²ãŒããå®çŸ©ããŸãã C# ãŸã㯠Visual Basic ã®ã©ã ãåŒã«æ £ããŠããªãå Žåã¯ãPLINQ ãš TPL ã®ã©ã ãåŒã®ãåç §ããŠãã ããã
Parallel.Invoke(() => DoSomeWork(), () => DoSomeOtherWork());
Parallel.Invoke(Sub() DoSomeWork(), Sub() DoSomeOtherWork())
æèš
Task ã«ãã£ãŠããã¯ã°ã©ãŠã³ãã§äœæããã Invoke ã€ã³ã¹ã¿ã³ã¹ã®æ°ã¯ãæäŸãããããªã²ãŒãã®æ°ãšå¿ ãããçãããšã¯éããŸããã TPL ã§ã¯ãç¹ã«å€æ°ã®ããªã²ãŒãã䜿çšããŠãããŸããŸãªæé©åãæ¡çšãããå ŽåããããŸãã
詳现ã«ã€ããŠã¯ããæ¹æ³: Parallel.Invoke ã䜿çšããŠäžŠåæäœãå®è¡ããããåç §ããŠãã ããã
ã¿ã¹ã¯ã®å®è¡ããã詳现ã«å¶åŸ¡ããããã¿ã¹ã¯ããå€ãè¿ãããããã«ã¯ãTask ãªããžã§ã¯ããããæç€ºçã«æäœããå¿ èŠããããŸãã
ã¿ã¹ã¯ã®æç€ºçãªäœæãšå®è¡
å€ãè¿ããªãã¿ã¹ã¯ã¯ãSystem.Threading.Tasks.Task ã¯ã©ã¹ã«ãã£ãŠè¡šãããŸãã å€ãè¿ãã¿ã¹ã¯ã¯ãSystem.Threading.Tasks.Task<TResult>ããç¶æ¿ããã Task ã¯ã©ã¹ã«ãã£ãŠè¡šãããŸãã ã¿ã¹ã¯ ãªããžã§ã¯ãã¯ãã€ã³ãã©ã¹ãã©ã¯ãã£ã®è©³çްãåŠçããã¿ã¹ã¯ã®æå¹æéãéããŠåŒã³åºãå ã®ã¹ã¬ããããã¢ã¯ã»ã¹ã§ããã¡ãœãããšããããã£ãæäŸããŸãã ããšãã°ãåžžã«ã¿ã¹ã¯ã® Status ããããã£ã«ã¢ã¯ã»ã¹ããããšã§ãã¿ã¹ã¯ãå®è¡ãéå§ããããå®äºãããããã£ã³ã»ã«ããããããããã¯äŸå€ãçºçãããã倿ããããšãã§ããŸãã ç¶æ ã¯ãTaskStatus åæäœã«ãã£ãŠè¡šãããŸãã
ã¿ã¹ã¯ãäœæãããšãã«ãã¿ã¹ã¯ãå®è¡ããã³ãŒããã«ãã»ã«åãããŠãŒã¶ãŒ ããªã²ãŒãããŠãŒã¶ãŒã«ä»äžããŸãã ããªã²ãŒãã¯ãååä»ãããªã²ãŒããå¿åã¡ãœããããŸãã¯ã©ã ãåŒãšããŠè¡šãããšãã§ããŸãã ã©ã ãåŒã«ã¯ã次ã®äŸã«ç€ºãããã«ãååä»ãã¡ãœããã®åŒã³åºããå«ããããšãã§ããŸãã ãã®äŸã«ã¯ãã³ã³ãœãŒã« ã¢ãŒã ã¢ããªã±ãŒã·ã§ã³ãçµäºããåã«ã¿ã¹ã¯ãå®è¡ãå®äºããããã«ãTask.Wait ã¡ãœããã®åŒã³åºããå«ãŸããŠããŸãã
using System;
using System.Threading;
using System.Threading.Tasks;
public class Lambda
{
public static void Main()
{
Thread.CurrentThread.Name = "Main";
// Create a task and supply a user delegate by using a lambda expression.
Task taskA = new Task( () => Console.WriteLine("Hello from taskA."));
// Start the task.
taskA.Start();
// Output a message from the calling thread.
Console.WriteLine($"Hello from thread '{Thread.CurrentThread.Name}'.");
taskA.Wait();
}
}
// The example displays output as follows:
// Hello from thread 'Main'.
// Hello from taskA.
// or
// Hello from taskA.
// Hello from thread 'Main'.
Imports System.Threading
Namespace Lambda
Module Example
Public Sub Main()
Thread.CurrentThread.Name = "Main"
' Create a task and supply a user delegate by using a lambda expression.
Dim taskA = New Task(Sub() Console.WriteLine("Hello from taskA."))
' Start the task.
taskA.Start()
' Output a message from the calling thread.
Console.WriteLine("Hello from thread '{0}'.",
Thread.CurrentThread.Name)
taskA.Wait()
End Sub
End Module
' The example displays output like the following:
' Hello from thread 'Main'.
' Hello from taskA.
End Namespace
Task.Run ã¡ãœããã䜿çšããŠã1 åã®æäœã§ã¿ã¹ã¯ãäœæããã³éå§ããããšãã§ããŸãã ã¿ã¹ã¯ã管çããããã«ãRun ã¡ãœããã¯ãçŸåšã®ã¹ã¬ããã«é¢é£ä»ããããŠããã¿ã¹ã¯ ã¹ã±ãžã¥ãŒã©ã«é¢ä¿ãªããæ¢å®ã®ã¿ã¹ã¯ ã¹ã±ãžã¥ãŒã©ã䜿çšããŸãã ã¿ã¹ã¯ã®äœæãšã¹ã±ãžã¥ãŒã«èšå®ããã詳现ã«å¶åŸ¡ããå¿ èŠããªãå Žåã¯ãRun ã¡ãœããã䜿çšããŠã¿ã¹ã¯ãäœæããã³éå§ããããšããå§ãããŸãã
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Run;
public class Example
{
public static void Main()
{
Thread.CurrentThread.Name = "Main";
// Define and run the task.
Task taskA = Task.Run( () => Console.WriteLine("Hello from taskA."));
// Output a message from the calling thread.
Console.WriteLine($"Hello from thread '{Thread.CurrentThread.Name}'.");
taskA.Wait();
}
}
// The example displays output as follows:
// Hello from thread 'Main'.
// Hello from taskA.
// or
// Hello from taskA.
// Hello from thread 'Main'.
Imports System.Threading
Namespace Run
Module Example
Public Sub Main()
Thread.CurrentThread.Name = "Main"
Dim taskA As Task = Task.Run(Sub() Console.WriteLine("Hello from taskA."))
' Output a message from the calling thread.
Console.WriteLine("Hello from thread '{0}'.",
Thread.CurrentThread.Name)
taskA.Wait()
End Sub
End Module
' The example displays output like the following:
' Hello from thread 'Main'.
' Hello from taskA.
End Namespace
TaskFactory.StartNew ã¡ãœããã䜿çšããŠã1 åã®æäœã§ã¿ã¹ã¯ãäœæããŠéå§ããããšãã§ããŸãã æ¬¡ã®äŸã«ç€ºãããã«ã次ã®å Žåã«ãã®ã¡ãœããã䜿çšã§ããŸãã
äœæãšã¹ã±ãžã¥ãŒã«ãåé¢ããå¿ èŠã¯ãããŸããã远å ã®ã¿ã¹ã¯äœæãªãã·ã§ã³ãŸãã¯ç¹å®ã®ã¹ã±ãžã¥ãŒã©ã®äœ¿çšãå¿ èŠã§ãã
Task.AsyncState ããããã£ã䜿çšããŠååŸã§ãã远å ã®ç¶æ ãã¿ã¹ã¯ã«æž¡ãå¿ èŠããããŸãã
using System;
using System.Threading;
using System.Threading.Tasks;
namespace TaskIntro;
class CustomData
{
public long CreationTime;
public int Name;
public int ThreadNum;
}
public class AsyncState
{
public static void Main()
{
Task[] taskArray = new Task[10];
for (int i = 0; i < taskArray.Length; i++)
{
taskArray[i] = Task.Factory.StartNew((Object obj) =>
{
CustomData data = obj as CustomData;
if (data == null) return;
data.ThreadNum = Thread.CurrentThread.ManagedThreadId;
},
new CustomData() { Name = i, CreationTime = DateTime.Now.Ticks });
}
Task.WaitAll(taskArray);
foreach (var task in taskArray)
{
var data = task.AsyncState as CustomData;
if (data != null)
Console.WriteLine("Task #{0} created at {1}, ran on thread #{2}.",
data.Name, data.CreationTime, data.ThreadNum);
}
}
}
// The example displays output like the following:
// Task #0 created at 635116412924597583, ran on thread #3.
// Task #1 created at 635116412924607584, ran on thread #4.
// Task #2 created at 635116412924607584, ran on thread #4.
// Task #3 created at 635116412924607584, ran on thread #4.
// Task #4 created at 635116412924607584, ran on thread #3.
// Task #5 created at 635116412924607584, ran on thread #3.
// Task #6 created at 635116412924607584, ran on thread #4.
// Task #7 created at 635116412924607584, ran on thread #4.
// Task #8 created at 635116412924607584, ran on thread #3.
// Task #9 created at 635116412924607584, ran on thread #4.
Imports System.Threading
Namespace AsyncState
Class CustomData
Public CreationTime As Long
Public Name As Integer
Public ThreadNum As Integer
End Class
Module Example
Public Sub Main()
Dim taskArray(9) As Task
For i As Integer = 0 To taskArray.Length - 1
taskArray(i) = Task.Factory.StartNew(Sub(obj As Object)
Dim data As CustomData = TryCast(obj, CustomData)
If data Is Nothing Then Return
data.ThreadNum = Environment.CurrentManagedThreadId
End Sub,
New CustomData With {.Name = i, .CreationTime = Date.Now.Ticks})
Next
Task.WaitAll(taskArray)
For Each task In taskArray
Dim data = TryCast(task.AsyncState, CustomData)
If data IsNot Nothing Then
Console.WriteLine("Task #{0} created at {1}, ran on thread #{2}.",
data.Name, data.CreationTime, data.ThreadNum)
End If
Next
End Sub
End Module
' The example displays output like the following:
' Task #0 created at 635116412924597583, ran on thread #3.
' Task #1 created at 635116412924607584, ran on thread #4.
' Task #2 created at 635116412924607584, ran on thread #4.
' Task #3 created at 635116412924607584, ran on thread #4.
' Task #4 created at 635116412924607584, ran on thread #3.
' Task #5 created at 635116412924607584, ran on thread #3.
' Task #6 created at 635116412924607584, ran on thread #4.
' Task #7 created at 635116412924607584, ran on thread #4.
' Task #8 created at 635116412924607584, ran on thread #3.
' Task #9 created at 635116412924607584, ran on thread #4.
End Namespace
Task ãš Task<TResult> ã¯ãã¡ãœããã FactoryãšããŠåŒã³åºãããšãã§ããããã«ãTaskFactoryã®æ¢å®ã®ã€ã³ã¹ã¿ã³ã¹ãè¿ãéç㪠Task.Factory.StartNew() ããããã£ãå
¬éããŸãã ãŸããæ¬¡ã®äŸã§ã¯ãã¿ã¹ã¯ã¯ System.Threading.Tasks.Task<TResult>åã§ãããããããããã®ã¿ã¹ã¯ã«ã¯ãèšç®ã®çµæãå«ããããªã㯠Task<TResult>.Result ããããã£ããããŸãã ã¿ã¹ã¯ã¯éåæçã«å®è¡ãããä»»æã®é åºã§å®äºããå¯èœæ§ããããŸãã èšç®ãå®äºããåã« Result ããããã£ã«ã¢ã¯ã»ã¹ãããšãå€ã䜿çšå¯èœã«ãªããŸã§åŒã³åºãå
ã®ã¹ã¬ããããããã¯ãããŸãã
using System;
using System.Threading.Tasks;
public class Result
{
public static void Main()
{
Task<Double>[] taskArray = { Task<Double>.Factory.StartNew(() => DoComputation(1.0)),
Task<Double>.Factory.StartNew(() => DoComputation(100.0)),
Task<Double>.Factory.StartNew(() => DoComputation(1000.0)) };
var results = new Double[taskArray.Length];
Double sum = 0;
for (int i = 0; i < taskArray.Length; i++) {
results[i] = taskArray[i].Result;
Console.Write("{0:N1} {1}", results[i],
i == taskArray.Length - 1 ? "= " : "+ ");
sum += results[i];
}
Console.WriteLine($"{sum:N1}");
}
private static Double DoComputation(Double start)
{
Double sum = 0;
for (var value = start; value <= start + 10; value += .1)
sum += value;
return sum;
}
}
// The example displays the following output:
// 606.0 + 10,605.0 + 100,495.0 = 111,706.0
Namespace Result
Module Example
Public Sub Main()
Dim taskArray() = {Task(Of Double).Factory.StartNew(Function() DoComputation(1.0)),
Task(Of Double).Factory.StartNew(Function() DoComputation(100.0)),
Task(Of Double).Factory.StartNew(Function() DoComputation(1000.0))}
Dim results(taskArray.Length - 1) As Double
Dim sum As Double
For i As Integer = 0 To taskArray.Length - 1
results(i) = taskArray(i).Result
Console.Write("{0:N1} {1}", results(i),
If(i = taskArray.Length - 1, "= ", "+ "))
sum += results(i)
Next
Console.WriteLine("{0:N1}", sum)
End Sub
Private Function DoComputation(start As Double) As Double
Dim sum As Double
For value As Double = start To start + 10 Step .1
sum += value
Next
Return sum
End Function
End Module
' The example displays the following output:
' 606.0 + 10,605.0 + 100,495.0 = 111,706.0
End Namespace
詳现ã«ã€ããŠã¯ããæ¹æ³: ã¿ã¹ã¯ããå€ãè¿ãããåç §ããŠãã ããã
ã©ã ãåŒã䜿çšããŠããªã²ãŒããäœæãããšããœãŒã¹ ã³ãŒãå
ã®ãã®æç¹ã§è¡šç€ºããããã¹ãŠã®å€æ°ã«ã¢ã¯ã»ã¹ã§ããŸãã ãã ããç¹ã«ã«ãŒãå
ã§ã¯ãã©ã ãã«ãã£ãŠå€æ°ãæ³å®ã©ããã«ãã£ããã£ãããªãå ŽåããããŸãã å埩ã®ãã³ã«å€æŽããããããå€ã§ã¯ãªã倿°ã®åç
§ã®ã¿ããã£ããã£ããŸãã æ¬¡ã®äŸã¯ããã®åé¡ã瀺ããŠããŸãã
CustomData ãªããžã§ã¯ããã€ã³ã¹ã¿ã³ã¹åããã«ãŒã ã«ãŠã³ã¿ãŒããªããžã§ã¯ãã®èå¥åãšããŠäœ¿çšããã©ã ãåŒã«ã«ãŒã ã«ãŠã³ã¿ãŒãæž¡ããŸãã ãã®äŸã®åºåã«ç€ºãããã«ãå CustomData ãªããžã§ã¯ãã«ã¯åãèå¥åããããŸãã
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Example.Iterations;
class CustomData
{
public long CreationTime;
public int Name;
public int ThreadNum;
}
public class IterationTwo
{
public static void Main()
{
// Create the task object by using an Action(Of Object) to pass in the loop
// counter. This produces an unexpected result.
Task[] taskArray = new Task[10];
for (int i = 0; i < taskArray.Length; i++) {
taskArray[i] = Task.Factory.StartNew( (Object obj) => {
var data = new CustomData() {Name = i, CreationTime = DateTime.Now.Ticks};
data.ThreadNum = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine($"Task #{data.Name} created at {data.CreationTime} on thread #{data.ThreadNum}.");
},
i );
}
Task.WaitAll(taskArray);
}
}
// The example displays output like the following:
// Task #10 created at 635116418427727841 on thread #4.
// Task #10 created at 635116418427737842 on thread #4.
// Task #10 created at 635116418427737842 on thread #4.
// Task #10 created at 635116418427737842 on thread #4.
// Task #10 created at 635116418427737842 on thread #4.
// Task #10 created at 635116418427737842 on thread #4.
// Task #10 created at 635116418427727841 on thread #3.
// Task #10 created at 635116418427747843 on thread #3.
// Task #10 created at 635116418427747843 on thread #3.
// Task #10 created at 635116418427737842 on thread #4.
Imports System.Threading
Namespace IterationsTwo
Class CustomData
Public CreationTime As Long
Public Name As Integer
Public ThreadNum As Integer
End Class
Module Example
Public Sub Main()
' Create the task object by using an Action(Of Object) to pass in the loop
' counter. This produces an unexpected result.
Dim taskArray(9) As Task
For i As Integer = 0 To taskArray.Length - 1
taskArray(i) = Task.Factory.StartNew(Sub(obj As Object)
Dim data As New CustomData With {.Name = i, .CreationTime = Date.Now.Ticks}
data.ThreadNum = Environment.CurrentManagedThreadId
Console.WriteLine("Task #{0} created at {1} on thread #{2}.",
data.Name, data.CreationTime, data.ThreadNum)
End Sub,
i)
Next
Task.WaitAll(taskArray)
End Sub
End Module
' The example displays output like the following:
' Task #10 created at 635116418427727841 on thread #4.
' Task #10 created at 635116418427737842 on thread #4.
' Task #10 created at 635116418427737842 on thread #4.
' Task #10 created at 635116418427737842 on thread #4.
' Task #10 created at 635116418427737842 on thread #4.
' Task #10 created at 635116418427737842 on thread #4.
' Task #10 created at 635116418427727841 on thread #3.
' Task #10 created at 635116418427747843 on thread #3.
' Task #10 created at 635116418427747843 on thread #3.
' Task #10 created at 635116418427737842 on thread #4.
End Namespace
ã³ã³ã¹ãã©ã¯ã¿ãŒãä»ããŠã¿ã¹ã¯ã«ç¶æ
ãªããžã§ã¯ããæäŸããããšã§ãåã€ãã¬ãŒã·ã§ã³ã®å€ã«ã¢ã¯ã»ã¹ã§ããŸãã æ¬¡ã®äŸã§ã¯ãCustomData ãªããžã§ã¯ããäœæãããšãã«ã«ãŒã ã«ãŠã³ã¿ãŒã䜿çšããŠåã®äŸã倿Žããã©ã ãåŒã«æž¡ããŸãã ãã®äŸã®åºåã«ç€ºãããã«ãå CustomData ãªããžã§ã¯ãã«ã¯ããªããžã§ã¯ããã€ã³ã¹ã¿ã³ã¹åãããæç¹ã§ã®ã«ãŒã ã«ãŠã³ã¿ãŒã®å€ã«åºã¥ãäžæã®èå¥åãå«ãŸããããã«ãªããŸããã
using System;
using System.Threading;
using System.Threading.Tasks;
class CustomData
{
public long CreationTime;
public int Name;
public int ThreadNum;
}
public class IterationOne
{
public static void Main()
{
// Create the task object by using an Action(Of Object) to pass in custom data
// to the Task constructor. This is useful when you need to capture outer variables
// from within a loop.
Task[] taskArray = new Task[10];
for (int i = 0; i < taskArray.Length; i++) {
taskArray[i] = Task.Factory.StartNew( (Object obj ) => {
CustomData data = obj as CustomData;
if (data == null)
return;
data.ThreadNum = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine($"Task #{data.Name} created at {data.CreationTime} on thread #{data.ThreadNum}.");
},
new CustomData() {Name = i, CreationTime = DateTime.Now.Ticks} );
}
Task.WaitAll(taskArray);
}
}
// The example displays output like the following:
// Task #0 created at 635116412924597583 on thread #3.
// Task #1 created at 635116412924607584 on thread #4.
// Task #3 created at 635116412924607584 on thread #4.
// Task #4 created at 635116412924607584 on thread #4.
// Task #2 created at 635116412924607584 on thread #3.
// Task #6 created at 635116412924607584 on thread #3.
// Task #5 created at 635116412924607584 on thread #4.
// Task #8 created at 635116412924607584 on thread #4.
// Task #7 created at 635116412924607584 on thread #3.
// Task #9 created at 635116412924607584 on thread #4.
Imports System.Threading
Namespace IterationsOne
Class CustomData
Public CreationTime As Long
Public Name As Integer
Public ThreadNum As Integer
End Class
Module Example
Public Sub Main()
' Create the task object by using an Action(Of Object) to pass in custom data
' to the Task constructor. This is useful when you need to capture outer variables
' from within a loop.
Dim taskArray(9) As Task
For i As Integer = 0 To taskArray.Length - 1
taskArray(i) = Task.Factory.StartNew(Sub(obj As Object)
Dim data As CustomData = TryCast(obj, CustomData)
If data Is Nothing Then Return
data.ThreadNum = Environment.CurrentManagedThreadId
Console.WriteLine("Task #{0} created at {1} on thread #{2}.",
data.Name, data.CreationTime, data.ThreadNum)
End Sub,
New CustomData With {.Name = i, .CreationTime = Date.Now.Ticks})
Next
Task.WaitAll(taskArray)
End Sub
End Module
' The example displays output like the following:
' Task #0 created at 635116412924597583 on thread #3.
' Task #1 created at 635116412924607584 on thread #4.
' Task #3 created at 635116412924607584 on thread #4.
' Task #4 created at 635116412924607584 on thread #4.
' Task #2 created at 635116412924607584 on thread #3.
' Task #6 created at 635116412924607584 on thread #3.
' Task #5 created at 635116412924607584 on thread #4.
' Task #8 created at 635116412924607584 on thread #4.
' Task #7 created at 635116412924607584 on thread #3.
' Task #9 created at 635116412924607584 on thread #4.
End Namespace
ãã®ç¶æ
ã¯ãã¿ã¹ã¯ ããªã²ãŒãã«åŒæ°ãšããŠæž¡ãããTask.AsyncState ããããã£ã䜿çšããŠã¿ã¹ã¯ ãªããžã§ã¯ãããã¢ã¯ã»ã¹ã§ããŸãã æ¬¡ã®äŸã¯ãåã®äŸã®ããªãšãŒã·ã§ã³ã§ãã
AsyncState ããããã£ã䜿çšããŠãã©ã ãåŒã«æž¡ããã CustomData ãªããžã§ã¯ãã«é¢ããæ
å ±ã衚瀺ããŸãã
using System;
using System.Threading;
using System.Threading.Tasks;
namespace TaskIntro;
class CustomData
{
public long CreationTime;
public int Name;
public int ThreadNum;
}
public class AsyncState
{
public static void Main()
{
Task[] taskArray = new Task[10];
for (int i = 0; i < taskArray.Length; i++)
{
taskArray[i] = Task.Factory.StartNew((Object obj) =>
{
CustomData data = obj as CustomData;
if (data == null) return;
data.ThreadNum = Thread.CurrentThread.ManagedThreadId;
},
new CustomData() { Name = i, CreationTime = DateTime.Now.Ticks });
}
Task.WaitAll(taskArray);
foreach (var task in taskArray)
{
var data = task.AsyncState as CustomData;
if (data != null)
Console.WriteLine("Task #{0} created at {1}, ran on thread #{2}.",
data.Name, data.CreationTime, data.ThreadNum);
}
}
}
// The example displays output like the following:
// Task #0 created at 635116412924597583, ran on thread #3.
// Task #1 created at 635116412924607584, ran on thread #4.
// Task #2 created at 635116412924607584, ran on thread #4.
// Task #3 created at 635116412924607584, ran on thread #4.
// Task #4 created at 635116412924607584, ran on thread #3.
// Task #5 created at 635116412924607584, ran on thread #3.
// Task #6 created at 635116412924607584, ran on thread #4.
// Task #7 created at 635116412924607584, ran on thread #4.
// Task #8 created at 635116412924607584, ran on thread #3.
// Task #9 created at 635116412924607584, ran on thread #4.
Imports System.Threading
Namespace AsyncState
Class CustomData
Public CreationTime As Long
Public Name As Integer
Public ThreadNum As Integer
End Class
Module Example
Public Sub Main()
Dim taskArray(9) As Task
For i As Integer = 0 To taskArray.Length - 1
taskArray(i) = Task.Factory.StartNew(Sub(obj As Object)
Dim data As CustomData = TryCast(obj, CustomData)
If data Is Nothing Then Return
data.ThreadNum = Environment.CurrentManagedThreadId
End Sub,
New CustomData With {.Name = i, .CreationTime = Date.Now.Ticks})
Next
Task.WaitAll(taskArray)
For Each task In taskArray
Dim data = TryCast(task.AsyncState, CustomData)
If data IsNot Nothing Then
Console.WriteLine("Task #{0} created at {1}, ran on thread #{2}.",
data.Name, data.CreationTime, data.ThreadNum)
End If
Next
End Sub
End Module
' The example displays output like the following:
' Task #0 created at 635116412924597583, ran on thread #3.
' Task #1 created at 635116412924607584, ran on thread #4.
' Task #2 created at 635116412924607584, ran on thread #4.
' Task #3 created at 635116412924607584, ran on thread #4.
' Task #4 created at 635116412924607584, ran on thread #3.
' Task #5 created at 635116412924607584, ran on thread #3.
' Task #6 created at 635116412924607584, ran on thread #4.
' Task #7 created at 635116412924607584, ran on thread #4.
' Task #8 created at 635116412924607584, ran on thread #3.
' Task #9 created at 635116412924607584, ran on thread #4.
End Namespace
ã¿ã¹ã¯ ID
ãã¹ãŠã®ã¿ã¹ã¯ã¯ãã¢ããªã±ãŒã·ã§ã³ ãã¡ã€ã³ã§äžæã«èå¥ãããæŽæ° ID ãåãåããTask.Id ããããã£ã䜿çšããŠã¢ã¯ã»ã¹ã§ããŸãã ãã® ID ã¯ãVisual Studio ãããã¬ãŒ 䞊åã¹ã¿ã㯠ããã³ ã¿ã¹ã¯ ãŠã£ã³ããŠã§ã¿ã¹ã¯æ å ±ã衚瀺ããå Žåã«äŸ¿å©ã§ãã ID ã¯é å»¶ããŠäœæãããŸããã€ãŸããèŠæ±ããããŸã§äœæãããŸããã ãã®ãããããã°ã©ã ãå®è¡ãããã³ã«ã¿ã¹ã¯ã® ID ãç°ãªãå ŽåããããŸãã ãããã¬ãŒã§ã¿ã¹ã¯ ID ã衚瀺ããæ¹æ³ã®è©³çްã«ã€ããŠã¯ããã¿ã¹ã¯ ãŠã£ã³ããŠã® ã®äœ¿çšãããã³ã䞊åã¹ã¿ã㯠ãŠã£ã³ã㊠ã䜿çšããããåç §ããŠãã ããã
ã¿ã¹ã¯ã®äœæãªãã·ã§ã³
ã¿ã¹ã¯ãäœæããã»ãšãã©ã® API ã¯ãTaskCreationOptions ãã©ã¡ãŒã¿ãŒãåãåããªãŒããŒããŒããæäŸããŸãã ãããã®ãªãã·ã§ã³ã® 1 ã€ä»¥äžãæå®ããããšã§ãã¿ã¹ã¯ ã¹ã±ãžã¥ãŒã©ã«ã¹ã¬ãã ããŒã«ã§ã¿ã¹ã¯ãã¹ã±ãžã¥ãŒã«ããæ¹æ³ãæç€ºããŸãã ãªãã·ã§ã³ã¯ããããããšã® ãŸã㯠æäœã䜿çšããŠçµåã§ããŸãã
次ã®äŸã¯ãLongRunning ãªãã·ã§ã³ãš PreferFairness ãªãã·ã§ã³ãæã€ã¿ã¹ã¯ã瀺ããŠããŸãã
var task3 = new Task(() => MyLongRunningMethod(),
TaskCreationOptions.LongRunning | TaskCreationOptions.PreferFairness);
task3.Start();
Dim task3 = New Task(Sub() MyLongRunningMethod(),
TaskCreationOptions.LongRunning Or TaskCreationOptions.PreferFairness)
task3.Start()
ã¿ã¹ã¯ãã¹ã¬ãããã«ã«ãã£ãŒ
åã¹ã¬ããã«ã¯ãé¢é£ä»ããããã«ã«ãã£ãš UI ã«ã«ãã£ãããããããã Thread.CurrentCulture ããããã£ãš Thread.CurrentUICulture ããããã£ã«ãã£ãŠå®çŸ©ãããŸãã ã¹ã¬ããã®ã«ã«ãã£ã¯ãæžåŒèšå®ãè§£æãäžŠã¹æ¿ããæååæ¯èŒæäœãªã©ã®æäœã§äœ¿çšãããŸãã ã¹ã¬ããã® UI ã«ã«ãã£ã¯ããªãœãŒã¹åç §ã§äœ¿çšãããŸãã
ã·ã¹ãã ã«ã«ãã£ã¯ãã¹ã¬ããã®æ¢å®ã®ã«ã«ãã£ãš UI ã«ã«ãã£ãå®çŸ©ããŸãã ãã ããCultureInfo.DefaultThreadCurrentCulture ããããã£ãš CultureInfo.DefaultThreadCurrentUICulture ããããã£ã䜿çšããŠãã¢ããªã±ãŒã·ã§ã³ ãã¡ã€ã³å ã®ãã¹ãŠã®ã¹ã¬ããã«æ¢å®ã®ã«ã«ãã£ãæå®ã§ããŸãã ã¹ã¬ããã®ã«ã«ãã£ãæç€ºçã«èšå®ããŠæ°ããã¹ã¬ãããèµ·åããå Žåãæ°ããã¹ã¬ããã¯åŒã³åºãå ã¹ã¬ããã®ã«ã«ãã£ãç¶æ¿ããŸããã代ããã«ããã®ã«ã«ãã£ãæ¢å®ã®ã·ã¹ãã ã«ã«ãã£ã§ãã ãã ããã¿ã¹ã¯ ããŒã¹ã®ããã°ã©ãã³ã°ã§ã¯ãã¿ã¹ã¯ãå¥ã®ã¹ã¬ããã§éåæçã«å®è¡ãããå Žåã§ããã¿ã¹ã¯ã¯åŒã³åºãå ã¹ã¬ããã®ã«ã«ãã£ã䜿çšããŸãã
次ã®äŸã§ã¯ãç°¡åãªå³ã瀺ããŸãã ã¢ããªã®çŸåšã®ã«ã«ãã£ããã©ã³ã¹èª (ãã©ã³ã¹) ã«å€æŽãããŸãã ãã©ã³ã¹èª (ãã©ã³ã¹) ãæ¢ã«çŸåšã®ã«ã«ãã£ã§ããå Žåã¯ãè±èª (ç±³åœ) ã«å€ãããŸãã ãã®åŸãæ°ããã«ã«ãã£ã§é貚å€ãšããŠæžåŒèšå®ãããæ°å€ãè¿ã formatDelegate ãšããååã®ããªã²ãŒããåŒã³åºããŸãã ããªã²ãŒããã¿ã¹ã¯ã«ãã£ãŠåæçãŸãã¯éåæçã«åŒã³åºããããã©ããã«é¢ä¿ãªããã¿ã¹ã¯ã¯åŒã³åºãå
ã¹ã¬ããã®ã«ã«ãã£ã䜿çšããŸãã
using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
decimal[] values = { 163025412.32m, 18905365.59m };
string formatString = "C2";
Func<String> formatDelegate = () => { string output = String.Format("Formatting using the {0} culture on thread {1}.\n",
CultureInfo.CurrentCulture.Name,
Thread.CurrentThread.ManagedThreadId);
foreach (var value in values)
output += String.Format("{0} ", value.ToString(formatString));
output += Environment.NewLine;
return output;
};
Console.WriteLine($"The example is running on thread {Thread.CurrentThread.ManagedThreadId}");
// Make the current culture different from the system culture.
Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}");
if (CultureInfo.CurrentCulture.Name == "fr-FR")
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
else
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
Console.WriteLine($"Changed the current culture to {CultureInfo.CurrentCulture.Name}.\n");
// Execute the delegate synchronously.
Console.WriteLine("Executing the delegate synchronously:");
Console.WriteLine(formatDelegate());
// Call an async delegate to format the values using one format string.
Console.WriteLine("Executing a task asynchronously:");
var t1 = Task.Run(formatDelegate);
Console.WriteLine(t1.Result);
Console.WriteLine("Executing a task synchronously:");
var t2 = new Task<String>(formatDelegate);
t2.RunSynchronously();
Console.WriteLine(t2.Result);
}
}
// The example displays the following output:
// The example is running on thread 1
// The current culture is en-US
// Changed the current culture to fr-FR.
//
// Executing the delegate synchronously:
// Formatting using the fr-FR culture on thread 1.
// 163 025 412,32 ⬠18 905 365,59 â¬
//
// Executing a task asynchronously:
// Formatting using the fr-FR culture on thread 3.
// 163 025 412,32 ⬠18 905 365,59 â¬
//
// Executing a task synchronously:
// Formatting using the fr-FR culture on thread 1.
// 163 025 412,32 ⬠18 905 365,59 â¬
Imports System.Globalization
Imports System.Threading
Module Example
Public Sub Main()
Dim values() As Decimal = {163025412.32D, 18905365.59D}
Dim formatString As String = "C2"
Dim formatDelegate As Func(Of String) = Function()
Dim output As String = String.Format("Formatting using the {0} culture on thread {1}.",
CultureInfo.CurrentCulture.Name,
Thread.CurrentThread.ManagedThreadId)
output += Environment.NewLine
For Each value In values
output += String.Format("{0} ", value.ToString(formatString))
Next
output += Environment.NewLine
Return output
End Function
Console.WriteLine("The example is running on thread {0}",
Thread.CurrentThread.ManagedThreadId)
' Make the current culture different from the system culture.
Console.WriteLine("The current culture is {0}",
CultureInfo.CurrentCulture.Name)
If CultureInfo.CurrentCulture.Name = "fr-FR" Then
Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
Else
Thread.CurrentThread.CurrentCulture = New CultureInfo("fr-FR")
End If
Console.WriteLine("Changed the current culture to {0}.",
CultureInfo.CurrentCulture.Name)
Console.WriteLine()
' Execute the delegate synchronously.
Console.WriteLine("Executing the delegate synchronously:")
Console.WriteLine(formatDelegate())
' Call an async delegate to format the values using one format string.
Console.WriteLine("Executing a task asynchronously:")
Dim t1 = Task.Run(formatDelegate)
Console.WriteLine(t1.Result)
Console.WriteLine("Executing a task synchronously:")
Dim t2 = New Task(Of String)(formatDelegate)
t2.RunSynchronously()
Console.WriteLine(t2.Result)
End Sub
End Module
' The example displays the following output:
'
' The example is running on thread 1
' The current culture is en-US
' Changed the current culture to fr-FR.
'
' Executing the delegate synchronously:
' Formatting Imports the fr-FR culture on thread 1.
' 163 025 412,32 ⬠18 905 365,59 â¬
'
' Executing a task asynchronously:
' Formatting Imports the fr-FR culture on thread 3.
' 163 025 412,32 ⬠18 905 365,59 â¬
'
' Executing a task synchronously:
' Formatting Imports the fr-FR culture on thread 1.
' 163 025 412,32 ⬠18 905 365,59 â¬
æèš
.NET Framework 4.6 ããåã®ããŒãžã§ã³ã® .NET Framework ã§ã¯ãã¿ã¹ã¯ã®ã«ã«ãã£ã¯ãåŒã³åºãå ã¹ã¬ããã®ã«ã«ãã£ã§ã¯ãªããå®è¡ãããã¹ã¬ããã®ã«ã«ãã£ã«ãã£ãŠæ±ºãŸããŸãã éåæã¿ã¹ã¯ã®å Žåãã¿ã¹ã¯ã§äœ¿çšãããã«ã«ãã£ã¯ãåŒã³åºãå ã¹ã¬ããã®ã«ã«ãã£ãšã¯ç°ãªãå ŽåããããŸãã
éåæã¿ã¹ã¯ãšã«ã«ãã£ã®è©³çްã«ã€ããŠã¯ãCultureInfo èšäºã®ãã«ã«ãã£ãšéåæã¿ã¹ã¯ ããŒã¹ã®æäœãã»ã¯ã·ã§ã³ãåç §ããŠãã ããã
ã¿ã¹ã¯ã®ç¶ç¶ã®äœæ
Task.ContinueWith ã¡ãœãããš Task<TResult>.ContinueWith ã¡ãœããã䜿çšãããšãç¶ç¶ã¿ã¹ã¯ ãå®äºãããšãã«éå§ããã¿ã¹ã¯ãæå®ã§ããŸãã ç¶ç¶ã¿ã¹ã¯ã®ããªã²ãŒãã¯ãç¶ç¶å ã¿ã¹ã¯ã®ç¶æ ã調ã¹ãããšãã§ããããã«ãç¶ç¶å ã¿ã¹ã¯ãžã®åç §ãæž¡ããŸãã ãŸããTask<TResult>.Result ããããã£ã®å€ãååŸããããšã§ãç¶ç¶å ã®åºåãç¶ç¶ã®å ¥åãšããŠäœ¿çšã§ããŸãã
次ã®äŸã§ã¯ãgetData ã¿ã¹ã¯ã¯ãTaskFactory.StartNew<TResult>(Func<TResult>) ã¡ãœããã®åŒã³åºãã«ãã£ãŠéå§ãããŸãã
processData ã¿ã¹ã¯ã¯ãgetData ãå®äºãããšèªåçã«éå§ãããdisplayData ãå®äºãããš processData ãéå§ãããŸãã
getData ã¯ãprocessData ã¿ã¹ã¯ã® getData ããããã£ãä»ã㊠Task<TResult>.Result ã¿ã¹ã¯ããã¢ã¯ã»ã¹ã§ããæŽæ°é
åãçæããŸãã
processData ã¿ã¹ã¯ã¯ããã®é
åãåŠçããTask<TResult>.ContinueWith<TNewResult>(Func<Task<TResult>,TNewResult>) ã¡ãœããã«æž¡ãããã©ã ãåŒã®æ»ãå€ã®åããåãæšè«ãããçµæãè¿ããŸãã
displayData ã¿ã¹ã¯ã¯ãprocessData ãå®äºãããšèªåçã«å®è¡ãããTuple<T1,T2,T3> ã©ã ãåŒã«ãã£ãŠè¿ããã processData ãªããžã§ã¯ãã¯ãdisplayData ã¿ã¹ã¯ã® processData ããããã£ãä»ã㊠Task<TResult>.Result ã¿ã¹ã¯ããã¢ã¯ã»ã¹ã§ããŸãã
displayData ã¿ã¹ã¯ã¯ãprocessData ã¿ã¹ã¯ã®çµæãåãåããŸãã åæ§ã®æ¹æ³ã§åãæšè«ãããResult ããããã£ã§ããã°ã©ã ã§äœ¿çšã§ããçµæãçæãããŸãã
using System;
using System.Threading.Tasks;
public class ContinuationOne
{
public static void Main()
{
var getData = Task.Factory.StartNew(() => {
Random rnd = new Random();
int[] values = new int[100];
for (int ctr = 0; ctr <= values.GetUpperBound(0); ctr++)
values[ctr] = rnd.Next();
return values;
} );
var processData = getData.ContinueWith((x) => {
int n = x.Result.Length;
long sum = 0;
double mean;
for (int ctr = 0; ctr <= x.Result.GetUpperBound(0); ctr++)
sum += x.Result[ctr];
mean = sum / (double) n;
return Tuple.Create(n, sum, mean);
} );
var displayData = processData.ContinueWith((x) => {
return String.Format("N={0:N0}, Total = {1:N0}, Mean = {2:N2}",
x.Result.Item1, x.Result.Item2,
x.Result.Item3);
} );
Console.WriteLine(displayData.Result);
}
}
// The example displays output similar to the following:
// N=100, Total = 110,081,653,682, Mean = 1,100,816,536.82
Namespace ContinuationsOne
Module Example
Public Sub Main()
Dim getData = Task.Factory.StartNew(Function()
Dim rnd As New Random()
Dim values(99) As Integer
For ctr = 0 To values.GetUpperBound(0)
values(ctr) = rnd.Next()
Next
Return values
End Function)
Dim processData = getData.ContinueWith(Function(x)
Dim n As Integer = x.Result.Length
Dim sum As Long
Dim mean As Double
For ctr = 0 To x.Result.GetUpperBound(0)
sum += x.Result(ctr)
Next
mean = sum / n
Return Tuple.Create(n, sum, mean)
End Function)
Dim displayData = processData.ContinueWith(Function(x)
Return String.Format("N={0:N0}, Total = {1:N0}, Mean = {2:N2}",
x.Result.Item1, x.Result.Item2,
x.Result.Item3)
End Function)
Console.WriteLine(displayData.Result)
End Sub
End Module
' The example displays output like the following:
' N=100, Total = 110,081,653,682, Mean = 1,100,816,536.82
End Namespace
Task.ContinueWith ã¯ã€ã³ã¹ã¿ã³ã¹ ã¡ãœããã§ãããããç¶ç¶ããã¿ã¹ã¯ããšã« Task<TResult> ãªããžã§ã¯ããã€ã³ã¹ã¿ã³ã¹åãã代ããã«ãã¡ãœããåŒã³åºããé£çµã§ããŸãã æ¬¡ã®äŸã¯ãåã®äŸãšæ©èœçã«åãã§ãããTask.ContinueWith ã¡ãœããã®åŒã³åºããé£çµããç¹ãç°ãªããŸãã ã¡ãœããåŒã³åºãã®ãã§ãŒã³ã«ãã£ãŠè¿ããã Task<TResult> ãªããžã§ã¯ãã¯ãæåŸã®ç¶ç¶ã¿ã¹ã¯ã§ãã
using System;
using System.Threading.Tasks;
public class ContinuationTwo
{
public static void Main()
{
var displayData = Task.Factory.StartNew(() => {
Random rnd = new Random();
int[] values = new int[100];
for (int ctr = 0; ctr <= values.GetUpperBound(0); ctr++)
values[ctr] = rnd.Next();
return values;
} ).
ContinueWith((x) => {
int n = x.Result.Length;
long sum = 0;
double mean;
for (int ctr = 0; ctr <= x.Result.GetUpperBound(0); ctr++)
sum += x.Result[ctr];
mean = sum / (double) n;
return Tuple.Create(n, sum, mean);
} ).
ContinueWith((x) => {
return String.Format("N={0:N0}, Total = {1:N0}, Mean = {2:N2}",
x.Result.Item1, x.Result.Item2,
x.Result.Item3);
} );
Console.WriteLine(displayData.Result);
}
}
// The example displays output similar to the following:
// N=100, Total = 110,081,653,682, Mean = 1,100,816,536.82
Namespace ContinuationsTwo
Module Example
Public Sub Main()
Dim displayData = Task.Factory.StartNew(Function()
Dim rnd As New Random()
Dim values(99) As Integer
For ctr = 0 To values.GetUpperBound(0)
values(ctr) = rnd.Next()
Next
Return values
End Function). _
ContinueWith(Function(x)
Dim n As Integer = x.Result.Length
Dim sum As Long
Dim mean As Double
For ctr = 0 To x.Result.GetUpperBound(0)
sum += x.Result(ctr)
Next
mean = sum / n
Return Tuple.Create(n, sum, mean)
End Function). _
ContinueWith(Function(x)
Return String.Format("N={0:N0}, Total = {1:N0}, Mean = {2:N2}",
x.Result.Item1, x.Result.Item2,
x.Result.Item3)
End Function)
Console.WriteLine(displayData.Result)
End Sub
End Module
' The example displays output like the following:
' N=100, Total = 110,081,653,682, Mean = 1,100,816,536.82
End Namespace
ContinueWhenAll ã¡ãœãããš ContinueWhenAny ã¡ãœããã䜿çšãããšãè€æ°ã®ã¿ã¹ã¯ããç¶è¡ã§ããŸãã
詳现ã«ã€ããŠã¯ããç¶ç¶ã¿ã¹ã¯ã䜿çšããã¿ã¹ã¯ã®é£çµããåç §ããŠãã ããã
ç¬ç«ããåã¿ã¹ã¯ã®äœæ
ã¿ã¹ã¯ã§å®è¡ãããŠãããŠãŒã¶ãŒ ã³ãŒããæ°ããã¿ã¹ã¯ãäœæããAttachedToParent ãªãã·ã§ã³ãæå®ããªãå Žåãæ°ããã¿ã¹ã¯ã¯ç¹å¥ãªæ¹æ³ã§èŠªã¿ã¹ã¯ãšåæãããŸããã ãã®çš®é¡ã®åæãããŠããªãã¿ã¹ã¯ã¯ããã¿ãããããå ¥ãåã¿ã¹ã¯ ãŸãã¯ãã¿ãããããåã¿ã¹ã¯ ãšåŒã°ããŸãã æ¬¡ã®äŸã¯ããã¿ãããããåã¿ã¹ã¯ã 1 ã€äœæããã¿ã¹ã¯ã瀺ããŠããŸãã
var outer = Task.Factory.StartNew(() =>
{
Console.WriteLine("Outer task beginning.");
var child = Task.Factory.StartNew(() =>
{
Thread.SpinWait(5000000);
Console.WriteLine("Detached task completed.");
});
});
outer.Wait();
Console.WriteLine("Outer task completed.");
// The example displays the following output:
// Outer task beginning.
// Outer task completed.
// Detached task completed.
Dim outer = Task.Factory.StartNew(Sub()
Console.WriteLine("Outer task beginning.")
Dim child = Task.Factory.StartNew(Sub()
Thread.SpinWait(5000000)
Console.WriteLine("Detached task completed.")
End Sub)
End Sub)
outer.Wait()
Console.WriteLine("Outer task completed.")
' The example displays the following output:
' Outer task beginning.
' Outer task completed.
' Detached child completed.
æèš
芪ã¿ã¹ã¯ã¯ãã¿ãããããåã¿ã¹ã¯ã®çµäºãåŸ æ©ããŸããã
åã¿ã¹ã¯ã®äœæ
ã¿ã¹ã¯ã§å®è¡ãããŠãããŠãŒã¶ãŒ ã³ãŒãã AttachedToParent ãªãã·ã§ã³ã䜿çšããŠã¿ã¹ã¯ãäœæããå Žåãæ°ããã¿ã¹ã¯ã¯èŠªã¿ã¹ã¯ã® ã¢ã¿ãããããåã¿ã¹ã¯ ãšåŒã°ããŸãã AttachedToParent ãªãã·ã§ã³ã䜿çšãããšã芪ã¿ã¹ã¯ãã¢ã¿ãããããŠãããã¹ãŠã®åã¿ã¹ã¯ã®å®äºãæé»çã«åŸ æ©ãããããæ§é åã¿ã¹ã¯ã®äžŠååŠçã衚ãããšãã§ããŸãã æ¬¡ã®äŸã¯ã10 åã®ã¢ã¿ãããããåã¿ã¹ã¯ãäœæãã芪ã¿ã¹ã¯ã瀺ããŠããŸãã ãã®äŸã§ã¯ãTask.Wait ã¡ãœãããåŒã³åºããŠã芪ã¿ã¹ã¯ãå®äºãããŸã§åŸ æ©ããŸãã ã¢ã¿ãããããåã¿ã¹ã¯ãå®äºãããŸã§æç€ºçã«åŸ æ©ããå¿ èŠã¯ãããŸããã
using System;
using System.Threading;
using System.Threading.Tasks;
public class Child
{
public static void Main()
{
var parent = Task.Factory.StartNew(() => {
Console.WriteLine("Parent task beginning.");
for (int ctr = 0; ctr < 10; ctr++) {
int taskNo = ctr;
Task.Factory.StartNew((x) => {
Thread.SpinWait(5000000);
Console.WriteLine($"Attached child #{x} completed.");
},
taskNo, TaskCreationOptions.AttachedToParent);
}
});
parent.Wait();
Console.WriteLine("Parent task completed.");
}
}
// The example displays output like the following:
// Parent task beginning.
// Attached child #9 completed.
// Attached child #0 completed.
// Attached child #8 completed.
// Attached child #1 completed.
// Attached child #7 completed.
// Attached child #2 completed.
// Attached child #6 completed.
// Attached child #3 completed.
// Attached child #5 completed.
// Attached child #4 completed.
// Parent task completed.
Imports System.Threading
Namespace Child
Module Example
Public Sub Main()
Dim parent = Task.Factory.StartNew(Sub()
Console.WriteLine("Parent task beginning.")
For ctr As Integer = 0 To 9
Dim taskNo As Integer = ctr
Task.Factory.StartNew(Sub(x)
Thread.SpinWait(5000000)
Console.WriteLine("Attached child #{0} completed.",
x)
End Sub,
taskNo, TaskCreationOptions.AttachedToParent)
Next
End Sub)
parent.Wait()
Console.WriteLine("Parent task completed.")
End Sub
End Module
' The example displays output like the following:
' Parent task beginning.
' Attached child #9 completed.
' Attached child #0 completed.
' Attached child #8 completed.
' Attached child #1 completed.
' Attached child #7 completed.
' Attached child #2 completed.
' Attached child #6 completed.
' Attached child #3 completed.
' Attached child #5 completed.
' Attached child #4 completed.
' Parent task completed.
End Namespace
芪ã¿ã¹ã¯ã§ã¯ãTaskCreationOptions.DenyChildAttach ãªãã·ã§ã³ã䜿çšããŠãä»ã®ã¿ã¹ã¯ã芪ã¿ã¹ã¯ã«ã¢ã¿ãããããªãããã«ããããšãã§ããŸãã 詳现ã«ã€ããŠã¯ããã¢ã¿ãããããåã¿ã¹ã¯ãšãã¿ãããããåã¿ã¹ã¯ããåç §ããŠãã ããã
ã¿ã¹ã¯ã®å®äºãåŸ æ©ããŠããŸã
System.Threading.Tasks.Task åãš System.Threading.Tasks.Task<TResult> åã«ã¯ãã¿ã¹ã¯ã®å®äºãåŸ æ©ã§ãã Task.Wait ã¡ãœããã®ãªãŒããŒããŒããããã€ãçšæãããŠããŸãã ããã«ãéç Task.WaitAll ã¡ãœãããš Task.WaitAny ã¡ãœããã®ãªãŒããŒããŒãã䜿çšãããšãã¿ã¹ã¯ã®é åã®äžéšãŸãã¯ãã¹ãŠãå®äºãããŸã§åŸ æ©ã§ããŸãã
éåžžã¯ã次ã®ããããã®çç±ã§ã¿ã¹ã¯ãåŸ æ©ããŸãã
ã¡ã€ã³ ã¹ã¬ããã¯ãã¿ã¹ã¯ã«ãã£ãŠèšç®ãããæçµçãªçµæã«äŸåããŸãã
ã¿ã¹ã¯ããã¹ããŒãããå¯èœæ§ã®ããäŸå€ãåŠçããå¿ èŠãããã
ãã¹ãŠã®ã¿ã¹ã¯ã®å®è¡ãå®äºããåã«ãã¢ããªã±ãŒã·ã§ã³ãçµäºããããšããããŸãã ããšãã°ãã³ã³ãœãŒã« ã¢ããªã±ãŒã·ã§ã³ã¯ã
Mainå ã®ãã¹ãŠã®åæã³ãŒã (ã¢ããªã±ãŒã·ã§ã³ ãšã³ã㪠ãã€ã³ã) ãå®è¡ãããåŸã«çµäºããŸãã
次ã®äŸã¯ãäŸå€åŠçã䌎ããªãåºæ¬çãªãã¿ãŒã³ã瀺ããŠããŸãã
Task[] tasks = new Task[3]
{
Task.Factory.StartNew(() => MethodA()),
Task.Factory.StartNew(() => MethodB()),
Task.Factory.StartNew(() => MethodC())
};
//Block until all tasks complete.
Task.WaitAll(tasks);
// Continue on this thread...
Dim tasks() =
{
Task.Factory.StartNew(Sub() MethodA()),
Task.Factory.StartNew(Sub() MethodB()),
Task.Factory.StartNew(Sub() MethodC())
}
' Block until all tasks complete.
Task.WaitAll(tasks)
' Continue on this thread...
äŸå€åŠçã瀺ãäŸã«ã€ããŠã¯ããäŸå€åŠç åç §ããŠãã ããã
äžéšã®ãªãŒããŒããŒãã§ã¯ã¿ã€ã ã¢ãŠããæå®ã§ããä»ã®ãªãŒããŒããŒãã¯å ¥åãã©ã¡ãŒã¿ãŒãšããŠè¿œå ã® CancellationToken ãåãåããåŸ æ©èªäœãããã°ã©ã ãŸãã¯ãŠãŒã¶ãŒå ¥åã«å¿çããŠåãæ¶ãããšãã§ããŸãã
ã¿ã¹ã¯ãåŸ æ©ãããšãTaskCreationOptions.AttachedToParentãªãã·ã§ã³ã䜿çšããŠäœæããããã®ã¿ã¹ã¯ã®ãã¹ãŠã®åã¿ã¹ã¯ãèªç¶ã«åŸ æ©ãããŸãã Task.Wait ã¯ãã¿ã¹ã¯ãæ¢ã«å®äºããŠããå Žåã¯çŽã¡ã«è¿ãããŸãã Task.Wait ã¡ãœããã¯ãã¿ã¹ã¯ã®å®äºåŸã« Task.Wait ã¡ãœãããåŒã³åºãããå Žåã§ããã¿ã¹ã¯ã«ãã£ãŠçºçããäŸå€ãã¹ããŒããŸãã
ã¿ã¹ã¯ãæ§æãã
Task ã¯ã©ã¹ãš Task<TResult> ã¯ã©ã¹ã«ã¯ãè€æ°ã®ã¿ã¹ã¯ãäœæããã®ã«åœ¹ç«ã€ããã€ãã®ã¡ãœãããçšæãããŠããŸãã ãããã®ã¡ãœããã¯ãäžè¬çãªãã¿ãŒã³ãå®è£ ããC#ãVisual BasicãF# ã«ãã£ãŠæäŸãããéåæèšèªæ©èœãããé©åã«äœ¿çšããŸãã ãã®ã»ã¯ã·ã§ã³ã§ã¯ãWhenAllãWhenAnyãDelayãããã³ FromResult ã¡ãœããã«ã€ããŠèª¬æããŸãã
Task.WhenAll
Task.WhenAll ã¡ãœããã¯ãè€æ°ã® Task ãŸã㯠Task<TResult> ãªããžã§ã¯ããå®äºãããŸã§éåæçã«åŸ æ©ããŸãã æäŸããããªãŒããŒããŒã ããŒãžã§ã³ã«ãããäžåäžãªã¿ã¹ã¯ã®ã»ãããåŸ æ©ããããšãã§ããŸãã ããšãã°ãè€æ°ã® Task ãªããžã§ã¯ããš Task<TResult> ãªããžã§ã¯ãã 1 ã€ã®ã¡ãœããåŒã³åºãããå®äºãããŸã§åŸ æ©ã§ããŸãã
Task.WhenAny
Task.WhenAny ã¡ãœããã¯ãè€æ°ã® Task ãŸã㯠Task<TResult> ãªããžã§ã¯ãã®ãããããå®äºãããŸã§éåæçã«åŸ æ©ããŸãã Task.WhenAll ã¡ãœãããšåæ§ã«ããã®ã¡ãœããã¯ãäžæ§ã§ãªãã¿ã¹ã¯ ã»ãããåŸ æ©ã§ãããªãŒããŒããŒããããããŒãžã§ã³ãæäŸããŸãã WhenAny ã¡ãœããã¯ã次ã®ã·ããªãªã§ç¹ã«åœ¹ç«ã¡ãŸãã
åé·æäœ: ããŸããŸãªæ¹æ³ã§å®è¡ã§ããã¢ã«ãŽãªãºã ãŸãã¯æäœãæ€èšããŠãã ããã WhenAny ã¡ãœããã䜿çšããŠãæåã«å®äºããæäœãéžæããŠãããæ®ãã®æäœãåãæ¶ãããšãã§ããŸãã
ã€ã³ã¿ãŒãªãŒãæäœ: å®äºããå¿ èŠãããè€æ°ã®æäœãéå§ããWhenAny ã¡ãœããã䜿çšããŠãåæäœã®çµäºæã«çµæãåŠçã§ããŸãã 1 ã€ã®æäœãå®äºãããã1 ã€ä»¥äžã®ã¿ã¹ã¯ãéå§ã§ããŸãã
èª¿æŽæäœ: WhenAny ã¡ãœããã䜿çšããŠãåæå®è¡æäœã®æ°ãå¶éããããšã§ãåã®ã·ããªãªãæ¡åŒµã§ããŸãã
æéåãã®æäœ: WhenAny ã¡ãœããã䜿çšããŠã1 ã€ä»¥äžã®ã¿ã¹ã¯ãšãç¹å®ã®æéãçµéããåŸã«çµäºããã¿ã¹ã¯ (Delay ã¡ãœããã«ãã£ãŠè¿ãããã¿ã¹ã¯ãªã©) ãéžæã§ããŸãã Delay ã¡ãœããã«ã€ããŠã¯ã次ã®ã»ã¯ã·ã§ã³ã§èª¬æããŸãã
Task.Delay (ã¿ã¹ã¯ã®é å»¶)
Task.Delay ã¡ãœããã¯ãæå®ããæå»ããåŸã«çµäºãã Task ãªããžã§ã¯ããçæããŸãã ãã®ã¡ãœããã䜿çšãããšãããŒã¿ãããŒãªã³ã°ããã«ãŒããæ§ç¯ããããã¿ã€ã ã¢ãŠããæå®ãããããŠãŒã¶ãŒå ¥åã®åŠçãé ããããããããšãã§ããŸãã
Task(T).FromResult
Task.FromResult ã¡ãœããã䜿çšãããšãäºåã«èšç®ãããçµæãä¿æãã Task<TResult> ãªããžã§ã¯ããäœæã§ããŸãã ãã®ã¡ãœããã¯ãTask<TResult> ãªããžã§ã¯ããè¿ãéåææäœãå®è¡ãããã® Task<TResult> ãªããžã§ã¯ãã®çµæãæ¢ã«èšç®ãããŠããå Žåã«äŸ¿å©ã§ãã FromResult ã䜿çšããŠãã£ãã·ã¥ã«ä¿æãããŠããéåæããŠã³ããŒãæäœã®çµæãååŸããäŸã«ã€ããŠã¯ããæ¹æ³: äºåèšç®æžã¿ã¿ã¹ã¯ãäœæããããåç §ããŠãã ããã
ã¿ã¹ã¯ã§ã®äŸå€ã®åŠç
ã¿ã¹ã¯ã 1 ã€ä»¥äžã®äŸå€ãã¹ããŒãããšãäŸå€ã¯ AggregateException äŸå€ã§ã©ãããããŸãã ãã®äŸå€ã¯ãã¿ã¹ã¯ãšçµåããã¹ã¬ããã«åæ ãããŸãã éåžžã¯ãã¿ã¹ã¯ãå®äºããã®ãåŸ
æ©ããŠããã¹ã¬ããããResult ããããã£ã«ã¢ã¯ã»ã¹ããã¹ã¬ããã§ãã ãã®åäœã«ããã.NET Framework ããªã·ãŒãé©çšãããŸããæ¢å®ã§ã¯ããã³ãã«ãããªãäŸå€ã¯ãã¹ãŠããã»ã¹ãçµäºããå¿
èŠããããŸãã åŒã³åºãå
ã®ã³ãŒãã¯ãtry/catch ãããã¯ã§æ¬¡ã®ããããã䜿çšããŠäŸå€ãåŠçã§ããŸãã
çµåã¹ã¬ããã¯ãã¿ã¹ã¯ãã¬ããŒãž ã³ã¬ã¯ã·ã§ã³ãããåã« Exception ããããã£ã«ã¢ã¯ã»ã¹ããŠäŸå€ãåŠçããããšãã§ããŸãã ãã®ããããã£ã«ã¢ã¯ã»ã¹ãããšãæªåŠçã®äŸå€ãããªããžã§ã¯ãã®çµäºæã«ããã»ã¹ãçµäºããäŸå€äŒéåäœãããªã¬ãŒããããšãé²ãããšãã§ããŸãã
äŸå€ãšã¿ã¹ã¯ã®è©³çްã«ã€ããŠã¯ããäŸå€åŠçããåç §ããŠãã ããã
ã¿ã¹ã¯ã®åãæ¶ã
Task ã¯ã©ã¹ã¯å調ãã£ã³ã»ã«ããµããŒããã.NET Framework 4 ã§å°å ¥ããã System.Threading.CancellationTokenSource ã¯ã©ã¹ãš System.Threading.CancellationToken ã¯ã©ã¹ãšå®å šã«çµ±åãããŠããŸãã System.Threading.Tasks.Task ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã®å€ãã¯ãCancellationToken ãªããžã§ã¯ããå ¥åãã©ã¡ãŒã¿ãŒãšããŠåãåããŸãã StartNew ããã³ Run ãªãŒããŒããŒãã®å€ãã«ãCancellationToken ãã©ã¡ãŒã¿ãŒãå«ãŸããŠããŸãã
ããŒã¯ã³ãäœæããåŸã§ CancellationTokenSource ã¯ã©ã¹ã䜿çšããŠãã£ã³ã»ã«èŠæ±ãçºè¡ã§ããŸãã ããŒã¯ã³ãåŒæ°ãšã㊠Task ã«æž¡ãããŠãŒã¶ãŒ ããªã²ãŒãå ã®åãããŒã¯ã³ãåç §ããŸããããã¯ããã£ã³ã»ã«èŠæ±ã«å¿çããåŠçãè¡ããŸãã
詳现ã«ã€ããŠã¯ããã¿ã¹ã¯ã®ãã£ã³ã»ã«ãããã³ãæ¹æ³: ã¿ã¹ã¯ãšãã®åãåãæ¶ãããåç §ããŠãã ããã
TaskFactory ã¯ã©ã¹
TaskFactory ã¯ã©ã¹ã¯ãã¿ã¹ã¯ãšç¶ç¶ã¿ã¹ã¯ãäœæããã³éå§ããããã®äžè¬çãªãã¿ãŒã³ãã«ãã»ã«åããéçã¡ãœãããæäŸããŸãã
æãäžè¬çãªãã¿ãŒã³ã¯ StartNewã§ããã1 ã€ã®ã¹ããŒãã¡ã³ãã§ã¿ã¹ã¯ãäœæããŠéå§ããŸãã
è€æ°ã®ç¶ç¶å ããç¶ç¶ã¿ã¹ã¯ãäœæããå Žåã¯ãContinueWhenAll ã¯ã©ã¹ã§ ContinueWhenAny ã¡ãœãããTask<TResult> ã¡ãœããããŸãã¯åçã®ã¡ãœããã䜿çšããŸãã 詳现ã«ã€ããŠã¯ããç¶ç¶ã¿ã¹ã¯ã䜿çšããã¿ã¹ã¯ã®é£çµããåç §ããŠãã ããã
éåæããã°ã©ãã³ã° ã¢ãã«ã®
BeginXããã³EndXã¡ãœããã Task ãŸã㯠Task<TResult> ã€ã³ã¹ã¿ã³ã¹ã«ã«ãã»ã«åããã«ã¯ãFromAsync ã¡ãœããã䜿çšããŸãã 詳现ã«ã€ããŠã¯ããTPL ãšåŸæ¥ã® .NET Framework éåæããã°ã©ãã³ã°ããåç §ããŠãã ããã
æ¢å®ã® TaskFactory ã«ã¯ãTask ã¯ã©ã¹ãŸã㯠Task<TResult> ã¯ã©ã¹ã®éçããããã£ãšããŠã¢ã¯ã»ã¹ã§ããŸãã TaskFactory ãçŽæ¥ã€ã³ã¹ã¿ã³ã¹åããCancellationTokenãTaskCreationOptions ãªãã·ã§ã³ãTaskContinuationOptions ãªãã·ã§ã³ããŸã㯠TaskSchedulerãå«ãããŸããŸãªãªãã·ã§ã³ãæå®ããããšãã§ããŸãã ã¿ã¹ã¯ ãã¡ã¯ããªã®äœææã«æå®ããããªãã·ã§ã³ã¯ãTaskåæã䜿çšããŠTaskCreationOptionsãäœæãããªãéããäœæãããã¹ãŠã®ã¿ã¹ã¯ã«é©çšãããŸãããã®å Žåãã¿ã¹ã¯ã®ãªãã·ã§ã³ã¯ã¿ã¹ã¯ ãã¡ã¯ããªã®ãªãã·ã§ã³ããªãŒããŒã©ã€ãããŸãã
ããªã²ãŒãã®ãªãã¿ã¹ã¯
å Žåã«ãã£ãŠã¯ãTask ã䜿çšããŠããŠãŒã¶ãŒ ããªã²ãŒãã§ã¯ãªãå€éšã³ã³ããŒãã³ãã«ãã£ãŠå®è¡ãããéåææäœãã«ãã»ã«åããããšãå¿ èŠã«ãªãå ŽåããããŸãã æäœãéåæããã°ã©ãã³ã° ã¢ãã«ã®éå§/çµäºãã¿ãŒã³ã«åºã¥ããŠããå Žåã¯ãFromAsync ã¡ãœããã䜿çšã§ããŸãã ããã§ãªãå Žåã¯ãTaskCompletionSource<TResult> ãªããžã§ã¯ãã䜿çšããŠæäœãã¿ã¹ã¯ã«ã©ããããããã°ã©ãã³ã° Task å©ç¹ã®äžéšãåŸãããšãã§ããŸãã ããšãã°ãäŸå€ã®äŒéãšç¶ç¶ã®ãµããŒããªã©ã§ãã 詳现ã«ã€ããŠã¯ãTaskCompletionSource<TResult>ãåç §ããŠãã ããã
ã«ã¹ã¿ã ã¹ã±ãžã¥ãŒã©
ã»ãšãã©ã®ã¢ããªã±ãŒã·ã§ã³ãŸãã¯ã©ã€ãã©ãªéçºè ã¯ãã¿ã¹ã¯ãå®è¡ãããããã»ããµãã¿ã¹ã¯ã®äœæ¥ãä»ã®ã¿ã¹ã¯ãšåæããæ¹æ³ããŸãã¯ã¿ã¹ã¯ã System.Threading.ThreadPoolã§ã©ã®ããã«ã¹ã±ãžã¥ãŒã«ãããŠãããã¯æ°ã«ããŸããã å¿ èŠãªã®ã¯ããã¹ã ã³ã³ãã¥ãŒã¿ãŒäžã§å¯èœãªéãå¹ççã«å®è¡ããããšã ãã§ãã ã¹ã±ãžã¥ãŒã«ã®è©³çްããã现ããå¶åŸ¡ããå¿ èŠãããå ŽåãTPL ã䜿çšãããšãæ¢å®ã®ã¿ã¹ã¯ ã¹ã±ãžã¥ãŒã©ã§äžéšã®èšå®ãæ§æããããã«ã¹ã¿ã ã¹ã±ãžã¥ãŒã©ãæå®ãããã§ããŸãã 詳现ã«ã€ããŠã¯ãTaskSchedulerãåç §ããŠãã ããã
é¢é£ããããŒã¿æ§é
TPL ã«ã¯ã䞊åããã³é 次ã·ããªãªã§åœ¹ç«ã€æ°ãããããªãã¯åãããã€ãçšæãããŠããŸãã ããã«ã¯ãSystem.Collections.Concurrent åå空éå ã®ããã€ãã®ã¹ã¬ãã ã»ãŒãã§é«éã§ã¹ã±ãŒã©ãã«ãªã³ã¬ã¯ã·ã§ã³ ã¯ã©ã¹ãšãããã€ãã®æ°ããåæã®çš®é¡ãå«ãŸããŸãã ããšãã°ãç¹å®ã®çš®é¡ã®ã¯ãŒã¯ããŒãã®å è¡ã¿ã¹ã¯ãããå¹çç㪠System.Threading.Semaphore ãš System.Threading.ManualResetEventSlimã§ãã .NET Framework 4 ã®ãã®ä»ã®æ°ããå (System.Threading.Barrier ã System.Threading.SpinLockãªã©) ã¯ã以åã®ãªãªãŒã¹ã§ã¯äœ¿çšã§ããªãã£ãæ©èœãæäŸããŸãã 詳现ã«ã€ããŠã¯ãã䞊åããã°ã©ãã³ã° ã®ããŒã¿æ§é ããåç §ããŠãã ããã
ã«ã¹ã¿ã ã¿ã¹ã¯ã®çš®é¡
System.Threading.Tasks.Task ãŸã㯠System.Threading.Tasks.Task<TResult>ããç¶æ¿ããªãããšããå§ãããŸãã 代ããã«ãAsyncState ããããã£ã䜿çšããŠã远å ã®ããŒã¿ãŸãã¯ç¶æ ã Task ãŸã㯠Task<TResult> ãªããžã§ã¯ãã«é¢é£ä»ãããããšããå§ãããŸãã æ¡åŒµã¡ãœããã䜿çšããŠãTask ã¯ã©ã¹ãš Task<TResult> ã¯ã©ã¹ã®æ©èœãæ¡åŒµããããšãã§ããŸãã æ¡åŒµã¡ãœããã®è©³çްã«ã€ããŠã¯ããæ¡åŒµã¡ãœãããããã³ãæ¡åŒµã¡ãœããããåç §ããŠãã ããã
Task ãŸã㯠Task<TResult>ããç¶æ¿ããå¿ èŠãããå Žåã¯ãRun ã¯ã©ã¹ãSystem.Threading.Tasks.TaskFactoryã¯ã©ã¹ãSystem.Threading.Tasks.TaskFactory<TResult>ã¯ã©ã¹ããŸã㯠System.Threading.Tasks.TaskCompletionSource<TResult> ã¯ã©ã¹ã䜿çšããŠã«ã¹ã¿ã ã¿ã¹ã¯ã®çš®é¡ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããããšã¯ã§ããŸããã ãããã®ã¯ã©ã¹ã¯ Task ãªããžã§ã¯ããš Task<TResult> ãªããžã§ã¯ãã®ã¿ãäœæããããã䜿çšã§ããŸããã ããã«ãTaskãTask<TResult>ãTaskFactoryãããã³ TaskFactory<TResult> ã«ãã£ãŠæäŸãããã¿ã¹ã¯ç¶ç¶ã¡ã«ããºã ã䜿çšããŠãã«ã¹ã¿ã ã¿ã¹ã¯ã®çš®é¡ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããããšã¯ã§ããŸããã ãããã®ã¯ã©ã¹ã¯ãTask ãªããžã§ã¯ããš Task<TResult> ãªããžã§ã¯ãã®ã¿ãäœæããããã䜿çšã§ããŸããã
é¢é£ã»ã¯ã·ã§ã³
| ã¿ã€ãã« | 説æ |
|---|---|
| ç¶ç¶ã¿ã¹ã¯ ã䜿çšããŠã¿ã¹ã¯ãé£çµãã | ç¶ç¶ã®ããã¿ã«ã€ããŠèª¬æããŸãã |
| ã¢ã¿ãããããåã¿ã¹ã¯ãšãã¿ãããããåã¿ã¹ã¯ | æ·»ä»ãããåã¿ã¹ã¯ãšåé¢ãããåã¿ã¹ã¯ã®éãã«ã€ããŠèª¬æããŸãã |
| ã¿ã¹ã¯ã®åãæ¶ã | Task ãªããžã§ã¯ãã«çµã¿èŸŒãŸããŠããåãæ¶ããµããŒãã«ã€ããŠèª¬æããŸãã |
| äŸå€åŠç | åæå®è¡ã¹ã¬ããã®äŸå€ãåŠçããæ¹æ³ã«ã€ããŠèª¬æããŸãã |
| æ¹æ³: Parallel.Invoke ã䜿çšããŠäžŠåæäœãå®è¡ãã | Invokeã®äœ¿ç𿹿³ã«ã€ããŠèª¬æããŸãã |
| æ¹æ³: ã¿ã¹ã¯ ããå€ãè¿ã | ã¿ã¹ã¯ããå€ãè¿ãæ¹æ³ã«ã€ããŠèª¬æããŸãã |
| æ¹æ³: ã¿ã¹ã¯ãšãã®åãåãæ¶ã | ã¿ã¹ã¯ãåãæ¶ãæ¹æ³ã«ã€ããŠèª¬æããŸãã |
| æ¹æ³: äºåèšç®æžã¿ã¿ã¹ã¯ ãäœæãã | Task.FromResult ã¡ãœããã䜿çšããŠããã£ãã·ã¥ã«ä¿æãããŠããéåæããŠã³ããŒãæäœã®çµæãååŸããæ¹æ³ã«ã€ããŠèª¬æããŸãã |
| æ¹æ³: 䞊åã¿ã¹ã¯ ã䜿çšããŠãã€ã㪠ããªãŒãèµ°æ»ãã | ã¿ã¹ã¯ã䜿çšããŠãã€ã㪠ããªãŒãèµ°æ»ããæ¹æ³ã«ã€ããŠèª¬æããŸãã |
| æ¹æ³: å ¥ãåã«ãªã£ãã¿ã¹ã¯ãè§£é€ãã | Unwrap æ¡åŒµã¡ãœããã䜿çšããæ¹æ³ã瀺ããŸãã |
| ããŒã¿ã®äžŠåå | For ãš ForEach ã䜿çšããŠãããŒã¿ã«å¯ŸããŠäžŠåã«ãŒããäœæããæ¹æ³ã«ã€ããŠèª¬æããŸãã |
| 䞊åããã°ã©ãã³ã° | .NET Framework 䞊åããã°ã©ãã³ã°ã®æäžäœããŒãã |
é¢é£é ç®
- 䞊åããã°ã©ãã³ã°
- .NET Core & .NET Standard ã䜿çšãã䞊åããã°ã©ãã³ã°ã® ãµã³ãã«