我目前只是继承了一些复杂的代码,遗憾的是我并不完全理解。它处理输入/输出到数据库的大量库存记录。解决方案非常大/先进,我仍然在c#的新方面。我遇到的问题是程序会定期抛出IO Exception
。它实际上并没有抛出失败代码,但它会混淆我们的输出数据。
try / catch块如下:
private static void ReadRecords(OleDbRecordReader recordReader, long maxRows, int executionTimeout, BlockingCollection<List<ProcessRecord>> processingBuffer, CancellationTokenSource cts, Job theStack, string threadName) {
ProcessRecord rec = null;
try {
Thread.CurrentThread.Name = threadName;
if(null == cts)
throw new InvalidOperationException("Passed CancellationToken was null.");
if(cts.IsCancellationRequested)
throw new InvalidOperationException("Passed CancellationToken is already been cancelled.");
long reportingFrequency = (maxRows <250000)?10000:100000;
theStack.FireStatusEvent("Opening "+ threadName);
recordReader.Open(maxRows, executionTimeout);
theStack.FireStatusEvent(threadName + " Opened");
theStack.FireInitializationComplete();
List<ProcessRecord> inRecs = new List<PIRecord>(500);
ProcessRecord priorRec = rec = recordReader.Read();
while(null != priorRec) { //-- note that this is priorRec, not Rec. We process one row in arrears.
if(cts.IsCancellationRequested)
theStack.FireStatusEvent(threadName + " cancelling due to request or error.");
cts.Token.ThrowIfCancellationRequested();
if(rec != null) //-- We only want to count the loop when there actually is a record.
theStack.RecordCountRead++;
if(theStack.RecordCountRead % reportingFrequency == 0)
theStack.FireProgressEvent();
if((rec != null) && (priorRec.SKU == rec.SKU) && (priorRec.Store == rec.Store) && (priorRec.BatchId == rec.BatchId))
inRecs.Add(rec); //-- just store it and keep going
else { //-- otherwise, we need to process it
processingBuffer.Add(inRecs.ToList(),cts.Token); //-- note that we don't enqueue the original LIST! That could be very bad.
inRecs.Clear();
if(rec != null) //-- Again, we need this check here to ensure that we don't try to enqueue the EOF null record.
inRecs.Add(rec); //-- Now, enqueue the record that fired this condition and start the loop again
}
priorRec = rec;
rec = recordReader.Read();
} //-- end While
}
catch(OperationCanceledException) {
theStack.FireStatusEvent(threadName +" Canceled.");
}
catch(Exception ex) {
theStack.FireExceptionEvent(ex);
theStack.FireStatusEvent("Error in RecordReader. Requesting cancellation of other threads.");
cts.Cancel(); // If an exception occurs, notify all other pipeline stages, then rethrow
// throw; //-- This will also propagate Cancellation, but that's OK
}
在我们的工作日志中,我们看到输出加载器停止,异常是
System.Core:管道坏了。
是否有人对可能导致此问题的想法有任何想法?更重要的是,进行大规模申请的人不再在这里。当我调试我的所有应用程序时,我能够在解决方案中添加断点并执行标准VS单步执行以查找问题。但是,这个应用程序非常庞大,并且在调试应用程序时会弹出一个GUI。我相信GUI是出于测试目的而制作的,但它阻碍了我实际上能够逐步完成所有操作。但是当.exe从我们的实际作业流运行时,没有GUI它只是按照预期的方式执行。
我要求的帮助是两件事:
只是建议可能导致这种情况的原因。 OleDB驱动程序可能是原因吗?我问的原因是因为我在2台不同的服务器上运行。一个测试,一个没有。具有新OleDB驱动程序版本的版本不会失败(我相信7.0,而失败的其他版本是6.0)。
是否有任何我可以添加的代码可以让我更好地指出可能导致管道损坏的原因?该错误仅定期发生。如果我马上重新开始工作,可能不会发生。我会说它有30%到40%的时间抛出异常。
如果您对结构有任何其他疑问,请告诉我。