下面是一个示例PLINQ查询我在一个Windows服务中定期运行:PLINQ查询中的评估顺序是什么?
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处理程序之后的下面的代码片段中,我可能会得到一个带有非0 Count的resultList?或者,异常意味着从不调用ToList(),并且如果引发异常,resultList将始终为空?
我意识到我与鲨鱼在使用这种多线程能力的情况下游泳时没有充分理解其含义。因此,这个问题!谢谢。
有趣!因此,在*执行上面的代码之后,* *有保证*,那么resultList将是一个任务列表,在Counts中等于emailsToSend IEnumerable? – oflahero
是的。因为异常将仅在'Task.WaitAll'调用中抛出。它将在列表创建后调用,因此列表将具有预期的长度。 – Kote
因此,任何进一步的处理都应该检查如下内容: 'resultList.Where(t => t.IsFaulted == false).Select(t => t.Result).Where(...',right? – oflahero