PLINQ 查询中的评估顺序是什么?
What is the order of evaluation in a PLINQ query?
下面是一个示例 PLINQ 查询,我 运行 定期在 Windows 服务中:
var resultList = new List<Task<SendMailResult>>();
try
{
resultList = emailsToSend
.AsParallel().WithDegreeOfParallelism(10)
.Select(async e =>
{
bool bSuccess = false;
if (await MailHelper.SendMailAsync(e.sTo, e.sSubject, e.sHTML) == true)
{
bSuccess = true;
}
return new SendMailResult
{
succeeded = bSuccess,
resultid = e.id
};
}).ToList();
Task.WaitAll(resultList.ToArray());
}
catch (AggregateException aggEx)
{
foreach (var ex in aggEx.InnerExceptions)
Console.Out.WriteLine(ex.Message);
}
我的问题是 - 如果在内部匿名 async Func<EmailToSend, Task<SendMailResult>>
中抛出异常(最有可能在调用 MailHelper.SendMailAsync() 时),那么将调用 AggregateException 处理程序 -是否会在任何时候调用以下 .ToList()
?
换句话说,是否有可能一些任务成功完成直到一个没有完成,并且在被 AggregateException 处理程序捕获后按照下面的代码片段,我可能有一个 resultList 具有非 0 计数?还是异常意味着永远不会调用 ToList(),如果抛出异常,resultList 将始终为空?
我意识到我正在使用这种多线程功能与鲨鱼一起游泳,但没有完全理解它的含义。因此问题!谢谢
.ToList()
将在任何时候调用,因为 Select
laziness 并且结果列表将包含所有任务。
执行将从 .ToList()
方法调用开始。 Select
只会提供IEnumerable
可以枚举到list.
如果某些任务因异常而失败,您将捕获它们,毕竟您将获得任务列表,其中某些任务将具有 Faulted
状态。
编辑:
异常抛出将由 Task.WaitAll
方法调用触发,因此列表将在之前创建,并将确切的项目计数为初始集合。
更新:
关于Task.WaitAll
内部结构:
如果你想知道它是如何工作的,你可以看看source code。
起初它 collects all incompleted tasks and then waits 完成这些任务。
然后它从所有任务中 collects all inner exceptions 然后将其作为单个 AggregateException
提出。
下面是一个示例 PLINQ 查询,我 运行 定期在 Windows 服务中:
var resultList = new List<Task<SendMailResult>>();
try
{
resultList = emailsToSend
.AsParallel().WithDegreeOfParallelism(10)
.Select(async e =>
{
bool bSuccess = false;
if (await MailHelper.SendMailAsync(e.sTo, e.sSubject, e.sHTML) == true)
{
bSuccess = true;
}
return new SendMailResult
{
succeeded = bSuccess,
resultid = e.id
};
}).ToList();
Task.WaitAll(resultList.ToArray());
}
catch (AggregateException aggEx)
{
foreach (var ex in aggEx.InnerExceptions)
Console.Out.WriteLine(ex.Message);
}
我的问题是 - 如果在内部匿名 async Func<EmailToSend, Task<SendMailResult>>
中抛出异常(最有可能在调用 MailHelper.SendMailAsync() 时),那么将调用 AggregateException 处理程序 -是否会在任何时候调用以下 .ToList()
?
换句话说,是否有可能一些任务成功完成直到一个没有完成,并且在被 AggregateException 处理程序捕获后按照下面的代码片段,我可能有一个 resultList 具有非 0 计数?还是异常意味着永远不会调用 ToList(),如果抛出异常,resultList 将始终为空?
我意识到我正在使用这种多线程功能与鲨鱼一起游泳,但没有完全理解它的含义。因此问题!谢谢
.ToList()
将在任何时候调用,因为 Select
laziness 并且结果列表将包含所有任务。
执行将从 .ToList()
方法调用开始。 Select
只会提供IEnumerable
可以枚举到list.
如果某些任务因异常而失败,您将捕获它们,毕竟您将获得任务列表,其中某些任务将具有 Faulted
状态。
编辑:
异常抛出将由 Task.WaitAll
方法调用触发,因此列表将在之前创建,并将确切的项目计数为初始集合。
更新:
关于Task.WaitAll
内部结构:
如果你想知道它是如何工作的,你可以看看source code。
起初它 collects all incompleted tasks and then waits 完成这些任务。
然后它从所有任务中 collects all inner exceptions 然后将其作为单个 AggregateException
提出。