C# PLINQ查询中的求值顺序是什么?
下面是我在Windows服务中定期运行的PLINQ查询示例:C# PLINQ查询中的求值顺序是什么?,c#,.net,multithreading,plinq,C#,.net,Multithreading,Plinq,下面是我在Windows服务中定期运行的PLINQ查询示例: var resultList = new List<Task<SendMailResult>>(); try { resultList = emailsToSend .AsParallel().WithDegreeOfParallelism(10) .Select(async e => { bool bSuccess = f
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);
}
var resultList=newlist();
尝试
{
resultList=emailsToSend
.AsParallel()。具有平行度(10)
.选择(异步e=>
{
bool bsucces=假;
if(wait MailHelper.SendMailAsync(e.sTo、e.ssObject、e.sHTML)==true)
{
b成功=真;
}
返回新的SendMailResult
{
成功=b成功,
resultid=e.id
};
}).ToList();
Task.WaitAll(resultList.ToArray());
}
捕获(聚合异常聚集)
{
foreach(aggEx.InnerExceptions中的var-ex)
控制台输出写入线(例如消息);
}
我的问题是-如果在内部匿名async Func
(很可能是在调用MailHelper.SendMailAsync()时)中抛出异常,然后将调用AggregateException处理程序-是否在任何时候调用了以下.ToList()
换句话说,是否有可能某些任务成功完成,直到某个任务没有完成,并且在AggregateException处理程序中捕获到下面的代码片段之后,我可能有一个非0计数的resultList?或者异常是否意味着永远不会调用ToList(),并且如果抛出异常,resultList将始终为空
我意识到我在与鲨鱼共游时使用了这种多线程的能力,而没有完全理解它的含义。这就是问题所在!谢谢。.ToList()
将在任何时候被调用,因为Select
,结果列表将包含所有任务。执行将从
.ToList()
方法调用开始<代码>选择仅提供可枚举到列表中的IEnumerable
。如果某些任务因异常而失败,您将捕获它们,然后您将获得任务列表,其中某些任务将处于
故障
状态
编辑:异常抛出将由
Task.WaitAll
方法调用触发,因此列表将在之前创建,并将精确的项目计数作为初始集合
更新:关于
Task.WaitAll
内部结构:如果你想知道它是如何工作的,你可以看看。
首先,您需要完成这些任务。
之后,它将从所有任务中删除,然后将其作为单个
聚合异常
引发 有趣!因此,可以保证,在执行上述代码之后,resultList将是一个任务列表,其数量等于emailsToSend IEnumerable?是的。因为异常只会在Task.WaitAll
调用上引发。它将在创建列表后被调用,因此列表将具有预期的长度。因此,任何进一步的处理都应该检查如下内容:resultList.Where(t=>t.IsFaulted==false)。选择(t=>t.Result)。Where(…
,对吗?如果你不在乎失败的结果,那么是的。太棒了,谢谢。如果这个问题在24小时内没有得到任何更深刻的答案,你的答案将被接受。