Run()
方法(第一个代码块)调用GetImpairedNodesFromCASpectrumAsync()
,然后调用GetRoutersOn3GBackupNodeStatusesAsync()
。
目前,如果GetRoutersOn3GBackupNodeStatusesAsync()
中的任何任务失败(由于异常),我会在Run()
方法中获得一个非常通用的异常,表示该任务已被取消。
如何确保调用堆栈中的任何任务最终将原始异常返回给run方法,以便我可以在那里处理它?</ p>
public override void Run(ref DevOpsScheduleEntryEventCollection events)
{
// I want to be able to catch any exceptions thrown from tasks in GetRoutersOn3GBackupNodeStatusesAsync()
Task<NetworkDeviceNodeStatus[]> CasImapairedNodesTask =
CasOperations.GetImpairedNodesFromCASpectrumAsync();
Task.WaitAll(CasImapairedNodesTask);
NetworkDeviceNodeStatus[] CasImpairedNodes = CasImapairedNodesTask.Result.ToArray();
}
internal virtual async Task<NetworkDeviceNodeStatus[]> GetImpairedNodesFromCASpectrumAsync()
{
#if DEBUG
Debug.WriteLine("Entering GetNodesInCriticalCondition()");
Stopwatch sw = new Stopwatch();
sw.Start();
#endif
// Execute both tasks. Throw an Exception if any errors.
try {
var nodesWithCircuitsDown = new List<NetworkDeviceNodeStatus>();
Task<NetworkDeviceNodeStatus[]> getAlarmingRoutersStatusesTask = null;
Task<NetworkDeviceNodeStatus[]> getActive3GRoutersStatusesTask = null;
getAlarmingRoutersStatusesTask = GetAlarmingRouterNodeStatusesAsync();
getActive3GRoutersStatusesTask = GetRoutersOn3GBackupNodeStatusesAsync();
await getAlarmingRoutersStatusesTask;
await getActive3GRoutersStatusesTask;
var threeGNodeStatuses = new List<NetworkDeviceNodeStatus>();
var offlineNodeStatuses = new List<NetworkDeviceNodeStatus>();
// Check if any nodes were hard down, but quickly came up on 3G
foreach (var status in getAlarmingRoutersStatusesTask.Result) {
var threeGStatus = getActive3GRoutersStatusesTask.Result.
FirstOrDefault(x => x.DeviceRetrievalId == status.DeviceRetrievalId);
if (threeGStatus == null) {
offlineNodeStatuses.Add(status);
}
}
foreach (var status in getActive3GRoutersStatusesTask.Result) {
threeGNodeStatuses.Add(status);
}
nodesWithCircuitsDown.AddRange(threeGNodeStatuses);
nodesWithCircuitsDown.AddRange(offlineNodeStatuses);
Trace.TraceInformation("{0} nodes with main data circuit down.", nodesWithCircuitsDown.Count);
#if DEBUG
sw.Stop();
Debug.WriteLine("Leaving GetNodesInCriticalCondition(). [" + sw.Elapsed.TotalSeconds + "]");
#endif
return nodesWithCircuitsDown.ToArray();
} catch (AggregateException ae) {
StringBuilder sb = new StringBuilder();
foreach (var e in ae.Flatten().InnerExceptions) {
sb.Append(e.Message + "\n");
}
throw new Exception("One of more errors occured while retrieving impaired nodes.\n" + sb.ToString());
}
}
virtual internal async Task<NetworkDeviceNodeStatus[]> GetRoutersOn3GBackupNodeStatusesAsync()
{
List<Branch3GInfo> branchActive3GInfos = new List<Branch3GInfo>();
var nodeStatuses = new List<NetworkDeviceNodeStatus>();
Task<Branch3GInfo[]> getActive3GRoutersTask = GetNodesOn3GBackupAsyncInternal();
NetworkDeviceNodeStatus[] deviceStatuses = new NetworkDeviceNodeStatus[0];
Task getBasicInfoTasks = await getActive3GRoutersTask.ContinueWith(async x =>
{
branchActive3GInfos = x.Result.Where(y => y.Status == Branch3GInfo.Branch3GStatus.Active).ToList();
Trace.TraceInformation("Found " + x.Result.Count() + " CAS Nodes on 3G backup.");
foreach (var branchActive3GInfo in branchActive3GInfos) {
await branchActive3GInfo.RouterInfo.GetBasicInfoAsync();
Trace.TraceInformation("Retrieved ModelBasicInfo for "
+ branchActive3GInfo.RouterInfo.GetBasicInfo());
}
}, TaskContinuationOptions.OnlyOnRanToCompletion);
await getBasicInfoTasks.ContinueWith(x =>
{
deviceStatuses = GetNetworkDeviceNodeStatuses(branchActive3GInfos.ToArray());
return deviceStatuses;
}, TaskContinuationOptions.OnlyOnRanToCompletion);
return deviceStatuses;
}
答案 0 :(得分:2)
您的问题是由seq 6 | parallel -j3 ./j'{}'
引起的,当条件不满足时会取消它的继续(即ContinueWith
)。
作为一般规则,请使用TaskContinuationOptions.OnlyOnRanToCompletion
代替await
:
ContinueWith