一、Task和Thread的区别
- 任务是架构在线程之上的,任务最终的执行还是要给到线程去执行的。
- 任务和线程之间不是一对一的关系,任务更像线程池,任务相比线程池有很小的开销和精确的控制。(总的来说Task的用法更为先进,在多线程的时候应该优先考虑Task)
二、Task的相关属性
1.status 当前状态类属性(较多)
- Created :任务已经初始化。
- WaitingForActivation:正在等待 .NET Framework 基础结构在内部将其激活并进行计划。
- WaitingToRun:已被计划执行,但尚未开始执行。
- Running:正在运行,但尚未完成。
- WaitingForChildrenToComplete:已完成执行,正在隐式等待附加的子任务完成。
- RanToCompletion:已成功完成执行的任务。
- 已通过对其自身的 CancellationToken 引发 OperationCanceledException 对取消进行了确认,此时该标记处于已发送信号状态;或者在该任务开始执行之前,已向该任务的CancellationToken 发出了信号
- Faulted:由于未处理异常的原因而完成的任务。
2. CurrentId:当前正在执行的任务id。(int)
3. IsCompleted:当前任务是否已经完成。(bool)
4. IsCanceled:任务是否由于被取消而完成。(bool)
5. ID:当前Task实例的Id。(int)
6. TaskCreationOptions 当前任务的优先级有以下七种:
- None:默认行为。
- PreferFairness: 以一种尽可能公平的方式安排任务,这意味着较早安排的任务将更可能较早运行,而较晚安排运行的任务将更可能较晚运行。
- LongRuning:指定任务将是长时间运行的、粗粒度的操作,涉及比细化的系统更少、更大的组件。可以通过过度订阅创建比可用硬件线程数更多的线程。 它还将提示任务计划程序:该任务需要附加线程,以使任务不阻塞本地线程池队列中其他线程或工作项的向前推动。
- AttachedToParent: 指定将任务附加到任务层次结构中的某个父级。
- DenyChildAttach:指定任何尝试作为附加的子任务执行。
- HideScheduler:防止环境计划程序被视为已创建任务的当前计划程序,当前计划程序。
- RunContinuationsAsynchronously:强制添加到当前任务的延续任务。
三、Task的常用方法
1.Wait(task) 等待当前task执行结束后执行。
代码演示:
Task tt = Task.Run(() =>
{
for (int i = 0; i < 300; i++)
{
Console.Write(1);
}
});
tt.Wait();
for (int i = 0; i < 300; i++)
{
Console.Write(2);
}
Console.ReadKey();
当代码中无tt.wait()时候,运行结果为1和2交替出现,反之会在tt任务运行完后,也就是输出1完成后再输出2。
2.WaitAll() 等待所有任务执行完成 。
3.WaitAny() 等待任意一个任务执行完成就执行。
4.ContinueWith() 第一个Task结束后自动执行下一个。
代码演示:
Task<int> tt = Task<int>.Run(() =>
{
for (int i = 0; i < 300; i++)
{
Console.Write(1);
}
return 10;
});
tt.ContinueWith(T1 =>
{
for (int i = 0; i < 300; i++)
{
Console.Write(2);
}
Console.WriteLine("tt的结果为:"+T1.Result);
});
运行结果为:
ContinueWith的用法是在一个任务执行完成之后执行的代码,需要注意的是T1为前一个任务返回的结果。
5.CancellationTokenSource 取消一个任务。