gpt4 book ai didi

c# - 如何将 AsParallel 与 async 和 await 关键字一起使用?

转载 作者:可可西里 更新时间:2023-11-01 03:08:41 28 4
gpt4 key购买 nike

我正在查看某人的异步示例代码,并注意到它的实现方式存在一些问题。在查看代码时,我想知道使用 as parallel 循环遍历列表是否比正常循环遍历列表更有效。

据我所知,两者在性能上的差异很小,都用完了每个处理器,并且都谈论了相同的完成时间。

这是第一种方式

var tasks= Client.GetClients().Select(async p => await p.Initialize());

这是第二个

var tasks = Client.GetClients().AsParallel().Select(async p => await p.Initialize());

我假设两者之间没有区别是否正确?

完整的程序可以在下面找到

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
RunCode1();
Console.WriteLine("Here");
Console.ReadLine();

RunCode2();
Console.WriteLine("Here");

Console.ReadLine();

}

private async static void RunCode1()
{
Stopwatch myStopWatch = new Stopwatch();
myStopWatch.Start();

var tasks= Client.GetClients().Select(async p => await p.Initialize());

Task.WaitAll(tasks.ToArray());
Console.WriteLine("Time ellapsed(ms): " + myStopWatch.ElapsedMilliseconds);
myStopWatch.Stop();
}
private async static void RunCode2()
{
Stopwatch myStopWatch = new Stopwatch();
myStopWatch.Start();
var tasks = Client.GetClients().AsParallel().Select(async p => await p.Initialize());
Task.WaitAll(tasks.ToArray());
Console.WriteLine("Time ellapsed(ms): " + myStopWatch.ElapsedMilliseconds);
myStopWatch.Stop();
}
}
class Client
{
public static IEnumerable<Client> GetClients()
{
for (int i = 0; i < 100; i++)
{
yield return new Client() { Id = Guid.NewGuid() };
}
}

public Guid Id { get; set; }

//This method has to be called before you use a client
//For the sample, I don't put it on the constructor
public async Task Initialize()
{
await Task.Factory.StartNew(() =>
{
Stopwatch timer = new Stopwatch();
timer.Start();
while(timer.ElapsedMilliseconds<1000)
{}
timer.Stop();

});
Console.WriteLine("Completed: " + Id);
}
}
}

最佳答案

应该几乎没有明显的区别。

在你的第一种情况下:

var tasks = Client.GetClients().Select(async p => await p.Initialize());

执行线程将(一次一个)开始为客户端列表中的每个元素执行InitializeInitialize 立即将方法排队到线程池并返回未完成的 Task

在你的第二种情况下:

var tasks = Client.GetClients().AsParallel().Select(async p => await p.Initialize());

执行线程将 fork 到线程池并(并行)开始为客户端列表中的每个元素执行InitializeInitialize 具有相同的行为:它立即将方法排队到线程池并返回。

这两个时间几乎相同,因为您只并行化了少量代码:将方法排队到线程池以及返回未完成的 Task

如果 Initialize 在其第一个 await 之前做了一些更长的(同步)工作,那么使用 AsParallel 可能是有意义的。

请记住,所有 async 方法(和 lambda)开始时都是同步执行的(请参阅 official FAQmy own intro post)。

关于c# - 如何将 AsParallel 与 async 和 await 关键字一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12564465/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com