Igo*_*sky 27 c# parallel-processing task
我有示例代码来比较Parallel方法和Task方法的处理时间.这个实验的目标是了解它们是如何工作的.
所以我的问题是:
Task只是ThreadPool.QueueUserWorkItem方法的包装吗?
public Task SomeLongOperation()
{
return Task.Delay(3000);
}
static void Main(string[] args)
{
Program p = new Program();
List<Task> tasks = new List<Task>();
tasks.Add(Task.Factory.StartNew(() => p.SomeLongOperation()));
tasks.Add(Task.Factory.StartNew(() => p.SomeLongOperation()));
var arr = tasks.ToArray();
Stopwatch sw = Stopwatch.StartNew();
Task.WaitAll(arr);
Console.WriteLine("Task wait all results: " + sw.Elapsed);
sw.Stop();
sw = Stopwatch.StartNew();
Parallel.Invoke(() => p.SomeLongOperation(), () => p.SomeLongOperation());
Console.WriteLine("Parallel invoke results: " + sw.Elapsed);
sw.Stop();
Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)这是我的处理结果:

编辑:
将代码更改为如下所示:
Program p = new Program();
Task[] tasks = new Task[2];
Stopwatch sw = Stopwatch.StartNew();
tasks[0] = Task.Factory.StartNew(() => p.SomeLongOperation());
tasks[1] = Task.Factory.StartNew(() => p.SomeLongOperation());
Task.WaitAll(tasks);
Console.WriteLine("Task wait all results: " + sw.Elapsed);
sw.Stop();
sw = Stopwatch.StartNew();
Parallel.Invoke(() => p.SomeLongOperation(), () => p.SomeLongOperation());
Console.WriteLine("Parallel invoke results: " + sw.Elapsed);
sw.Stop();
Run Code Online (Sandbox Code Playgroud)
我的新结果:

编辑2: 当我用Parallel.Invoke替换代码为第一,而Task.WaitAll替换为第二时,情况已经被更改为cardinally.现在Parallel比较慢.这让我想到了我的估计不正确.我改变代码看起来像这样:
Program p = new Program();
Task[] tasks = new Task[2];
Stopwatch sw = null;
for (int i = 0; i < 10; i++)
{
sw = Stopwatch.StartNew();
Parallel.Invoke(() => p.SomeLongOperation(), () => p.SomeLongOperation());
string res = sw.Elapsed.ToString();
Console.WriteLine("Parallel invoke results: " + res);
sw.Stop();
}
for (int i = 0; i < 10; i++)
{
sw = Stopwatch.StartNew();
tasks[0] = Task.Factory.StartNew(() => p.SomeLongOperation());
tasks[1] = Task.Factory.StartNew(() => p.SomeLongOperation());
Task.WaitAll(tasks);
string res2 = sw.Elapsed.ToString();
Console.WriteLine("Task wait all results: " + res2);
sw.Stop();
}
Run Code Online (Sandbox Code Playgroud)
这是我的新结果:


现在我可以建议这个实验更加明确.结果几乎相同.有时并行,有时任务更快.现在我的问题是:
1.我应该在哪里使用Task和Parallel?
2.与Parallel相比,使用Task有什么好处?
3. Task是ThreadPool.QueueUserWorkItem方法的包装吗?
欢迎提供任何可以澄清这些问题的有用信息.
Parallel和Task都是ThreadPool的包装器.并行调用也等待所有任务完成.
与您的问题相关:
使用Task,Parallel或ThreadPool取决于执行并行任务时需要的控制粒度.我个人习惯了Task.Factory.StartNew(),但那是个人观点.这同样涉及到ThreadPool.QueueUserWorkItem()
附加信息:由于内部初始化,对Parallel.Invoke()和Task.Factory.StartNew()的第一次调用可能会变慢.
如果您启动非通用任务(即“没有返回值的无效任务”)并立即Wait为它们使用,请Parallel.Invoke改用。你的意图对读者来说是显而易见的。
在以下情况下使用任务:
TaskCreationOptions功能CancellationToken或TaskScheduler功能但不想使用ParallelOptions是的,您可以绕过其中的一些,例如,Parallel.Invoke(() => p.OpWithToken(CancellationToken)但这会混淆您的意图。Parallel.Invoke是为了使用尽可能多的 CPU 能力做一堆工作。它完成了,它不会死锁,你事先知道这一点。
不过你的测试很可怕。危险信号是您的长时间操作是等待 3000 毫秒,但您的测试花费的时间不到十分之一毫秒。
Task.Factory.StartNew(() => p.SomeLongOperation());
Run Code Online (Sandbox Code Playgroud)
StartNew 接受一个Action,并在一个新的main 中 执行它Task。该操作() => SomeLongOperation()创建一个子任务 Task。此子任务创建(未完成)后,调用SomeLongOperation()返回,Action完成。所以主 Task在十毫秒后已经完成,而你没有参考的两个子任务仍在后台运行。Parallel 路径还创建了两个子任务,它根本不跟踪并返回。
正确的方法是tasks[0] = p.SomeLongOperation();,它将一个正在运行的任务分配给数组。然后WaitAll检查此任务的完成情况。
| 归档时间: |
|
| 查看次数: |
16809 次 |
| 最近记录: |