【发布时间】:2015-11-11 17:09:48
【问题描述】:
我正在尝试使用 WPF、C# 开发一个小型应用程序。我在尝试使用库 TPL 时遇到了一个问题,尤其是异常处理。问题是 AggregateException 从未被捕获,并且程序在我作为任务传递的方法中显示异常。这是我的代码。我删除了不必要的代码:
private void RefreshOldDossierFinancementCommandExecute(KeyEventArgs e)
{
bool processIt = false;
if (e != null && e.Key == Key.Enter)
processIt = true;
if (e == null || processIt == true)
{
TaskInProgress = true;
SBMessage = "Query In progress...";
var uischeduler = TaskScheduler.FromCurrentSynchronizationContext();
var refreshold = Task.Factory.StartNew(() =>
RefreshOldDossierFinancement(DossierFinancementEnteredKey));
refreshold.ContinueWith(task => { TaskInProgress = false; },
CancellationToken.None,
TaskContinuationOptions.NotOnFaulted, uischeduler);
try
{
refreshold.Wait();
}
catch (AggregateException aex) //This Exception is never fired
{
Messenger.Default.Send(new ExceptionMessageRefresh(aex), "DossierFinancement");
}
}
}
private void RefreshOldDossierFinancement(long dfId)
{
TotalContrats = 0.000M;
TotalMefs = 0.000M;
TotalCommandes = 0.000M;
decimal phb = 0.000M;
decimal pctr = 0.000M;
decimal pmef = 0.000M;
PercentageHorsBilan = "(0%)";
PercentageContrats = "(0%)";
PercentageMef = "(0%)";
DossierNumber = "";
using (UnitOfWork cx = new UnitOfWork(_currentLog))
{
// try
{
IDossierFinancementRepository sr = new DossierFinancementRepository(cx, _currentLog);
IDossierFinancementManagementService dfms = new DossierFinancementManagementService(_currentLog, sr);
IDataTraceRepository dtr = new DataTraceRepository(cx, _currentLog);
IDataTraceManagementService dtms = new DataTraceManagementService(_currentLog, dtr);
CurrentDossierFinancement = dfms.FindById(dfId);
//I put this code in comment to force a nullReferenceException exception
/*if (CurrentDossierFinancement == null) //Not Found
Messenger.Default.Send<NotificationMessage>(new NotificationMessage("Dossier Financement n° " + dfId.ToString() + " introuvable."),"DossierFinancementError");
else*/
{
//The debugger stops here with NullRefrenceException Exception
// I want this exception to be captured in AggregateException
DossierFinancementEnteredKey = CurrentDossierFinancement.DossierId;
DossierNumber = "N° " + DossierFinancementEnteredKey.ToString();
RequestNature = (CurrentDossierFinancement.InvestmentGoal == 0) ? "Création" : (CurrentDossierFinancement.InvestmentGoal == 1) ? "Renouvellement" : "Extension";
EtatDossier = (CurrentDossierFinancement.Status == 1) ? "En cours" : (CurrentDossierFinancement.Status == 2) ? "Approuvé" : "Rejeté";
if (CurrentDossierFinancement.ClientId != null)
{
CustomerCode = (long)CurrentDossierFinancement.ClientId;
CustomerName = CurrentDossierFinancement.Client.NomCli;
}
else
{
CustomerCode = 0;
if (CurrentDossierFinancement.ClientType == 1)
CustomerName = CurrentDossierFinancement.Name + " " + CurrentDossierFinancement.FirstName;
else
CustomerName = CurrentDossierFinancement.CompanyName;
}
if (CurrentDossierFinancement.Contrat != null)
{
TotalContrats = CurrentDossierFinancement.Contrat.Montant;
TotalHorsBilan = CurrentDossierFinancement.Contrat.Montant;
pctr = Math.Round((TotalContrats / CurrentDossierFinancement.Montant) * 100, 0);
PercentageContrats = "(" + pctr.ToString() + "%)";
if (CurrentDossierFinancement.Contrat.Mefs != null)
{
TotalMefs = CurrentDossierFinancement.Contrat.Mefs.Sum(x => x.Montant);
pmef = Math.Round((TotalMefs / CurrentDossierFinancement.Montant) * 100, 0);
PercentageMef = "(" + pmef.ToString() + "%)";
}
TotalHorsBilan = TotalContrats - TotalMefs;
phb = Math.Round((TotalHorsBilan / CurrentDossierFinancement.Montant) * 100, 0);
PercentageHorsBilan = "(" + phb.ToString() + "%)";
}
//Extraire la trace
List<DataTrace> traceList = dtms.GetTrace(DossierFinancementEnteredKey, "DossierFinancement").ToList();
DataTrace newRecord = traceList.Where(xx => string.Equals(xx.ActionLib, "New", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
if (newRecord != null)
{
CreatedBy = newRecord.Coduser;
CreatedAt = newRecord.ActionDate.ToString();
}
}
}
/*
catch (Exception ex)
{
throw ex;
}*/
}
}
我测试了下面的代码,还是不行:
Task.Run(() =>
{
RefreshOldDossierFinancement(DossierFinancementEnteredKey);
}
catch (AggregateException aex)
{
Messenger.Default.Send(new ExceptionMessageRefresh(aex), "DossierFinancement");
}}).ContinueWith(task => { TaskInProgress = false; },
CancellationToken.None,
TaskContinuationOptions.NotOnFaulted, uischeduler
);
【问题讨论】:
-
你为什么要在线程池上排队
Task然后立即与Task.Wait同步阻塞? -
我是 TPL 的新手。当 Task.Run((() => ...) 不起作用时,我尝试了这个。
-
您期望哪个内部异常?
-
NullRefrenceException。这里我在主键中输入 0,然后搜索返回 null。如您所见,我在测试返回的实体是否为空的行周围添加了注释,以强制触发异常。最终目标,我想尝试在使用 TPL 时在自定义窗口中显示异常
标签: c# wpf task-parallel-library