我有一个Windows服务,可以生成有效的对象。这些对象有两种方法可以作为任务启动。在内务或关机期间,我在对象上调用一个告诉任务停止的Stop方法。我有一个为对象创建的任务列表'方法,所以我为他们做了一个Task.WaitAll。但是,我在关机期间收到NullReferenceException。我认为其中一个Task对象是null,所以我用.Where(pt => pt!= null).ToArray()测试它,但是没有用。
这是一个片段:
var peProcessor = new PrintExpertProcessor(runId);
processorTasks.Add(Task.Factory.StartNew(() => peProcessor.ProcessRun()));
processorTasks.Add(Task.Factory.StartNew(() => peProcessor.StartMonitor()));
processors.Add(peProcessor);
// Later in the code
Task.WaitAll(processorTasks.ToArray()); // System.AggregateException: System.NullReferenceException:
我认为Task不是null,而是原始处理器对象为null。但是,我不确定如何检查或阻止这种情况。我是对“任务”的新手,所以我仍然不知所措。
思想?
完整错误消息:
System.AggregateException: System.NullReferenceException: Object reference not set to an instance of an object.
at WOW.PrintExpert.AwdProcessor.Code.PrintExpertProcessor.StopProcessor()
at WOW.PrintExpert.AwdProcessor.Code.PrintExpertProcessor.ProcessRun()
at System.Threading.Tasks.Task.Execute()
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout, CancellationToken cancellationToken)
at WOW.PrintExpert.AwdProcessorService.ProcessorService.OnStop()
---> (Inner Exception #0) System.NullReferenceException: Object reference not set to an instance of an object.
at WOW.PrintExpert.AwdProcessor.Code.PrintExpertProcessor.StopProcessor()
at WOW.PrintExpert.AwdProcessor.Code.PrintExpertProcessor.ProcessRun()
at System.Threading.Tasks.Task.Execute()<---
答案 0 :(得分:2)
正如DJ KRAZE链接的文档中所解释的那样,AggregateException
意味着其中一个任务抛出了NullReferenceException(并不是因为processorTasks集合是null,也不是它的一个项目,因为它会产生一个ArgumentNullException
)
检查NullReferenceException的调用堆栈(可以在AggregateException.InnerExceptions
属性中找到),或者只是将调试器设置为在抛出的NullReferenceException
上中断,以便找到实际的异常。
答案 1 :(得分:0)
好的,这就是我的用途。它看起来像我想要的那样正常运行。
// Service class
private Dictionary<int, Task> processorMonitorTasks = new Dictionary<int, Task>();
private Dictionary<int, Task> processorTasks = new Dictionary<int, Task>();
收到新作品时:
// Spawn new processor object
var peProcessor = new PrintExpertProcessor(runId);
// Create tasks for the processors methods
processorTasks.Add(runId, Task.Run(() => peProcessor.ProcessRun()));
processorMonitorTasks.Add(runId, Task.Run(() => peProcessor.StartMonitor()));
// Add the processor the collection
processors.Add(peProcessor);
当服务关闭时,它会执行以下操作:
// Copying the object references to a new list prevents enumeration changed exceptions.
foreach (var proc in processors.ToList())
{
if (proc != null && !proc.IsStopped)
{
// Direct that each object come to a stop
proc.StopProcessor();
}
}
// Now, wait for each one to stop.
Task.WaitAll(processorTasks.Values.ToArray());
Task.WaitAll(processorMonitorTasks.Values.ToArray());