I am receiving an intermittent exception in a WinForms application that is run on multiple servers. There seems to be no consistent precursor to these failures as the same code will execute successfully on the same one day and then fail the following day.
Here is the code in which the exception is taking place:
private void Cr22(RCItem anItem)
{
string[] elements = anItem.param.Split('#');
if (elements.Length == 3)
{
if (OnMessage != null)
{
OnMessage("\tPartner : " + anItem.partner);
OnMessage("\tProgram : " + anItem.program);
}
AddLogMessage(anItem, "Start of processing");
AddLogMessage(anItem, "Calculating combined total");
RCDateRange range = GetMonthCalcDays(anItem, anItem.date, 1);
DataTable table = new DataTable();
table.Columns.Add("Date", typeof(string));
table.Columns.Add("Amount", typeof(double));
foreach (string dateString in range.allDates)
{
string sql = string.Format("SELECT c.Short_Date AS [Date], c.Day FROM dbo.CS_Calendar c " +
"INNER JOIN dbo.CS_Calendar PreviousDay ON CONVERT(INT, c.Previous_Date) = CONVERT(INT, PreviousDay.Short_Date) WHERE c.Short_Date = '{0}'", dateString);
int dayOfWeek = 0;
using (OleDbCommand cmd = new OleDbCommand(sql, _aConn))
{
cmd.CommandTimeout = _timeout;
using (OleDbDataReader reader = cmd.ExecuteReader())
{
if (reader != null && reader.HasRows)
while (reader.Read())
dayOfWeek = Convert.ToInt32(reader.GetValue(1));
}
}
if (dayOfWeek == 0)
{
AddLogMessage(anItem, "Invalid Date Supplied");
return;
}
List<string> prevDaysList = new List<string>();
if (dayOfWeek > 1 && dayOfWeek < 7)
{
if (dayOfWeek >= 2 && dayOfWeek <= 4)
prevDaysList = GetPreviousXDays(dateString, 5, false);
else
prevDaysList = GetPreviousXDays(dateString, 3, false);
sql = string.Format("**redacted**", StringListAsIn(prevDaysList));
AddLogMessage(anItem, sql);
double val = 0;
// Get the values for the specified date range in the previous month using the specified SQL query
using (OleDbCommand cmd = new OleDbCommand(sql, _aConn))
{
cmd.CommandTimeout = _timeout;
using (OleDbDataReader reader = cmd.ExecuteReader())
{
if (reader != null && reader.HasRows)
while (reader.Read())
val = val + Convert.ToDouble(reader.GetValue(1));
}
}
AddLogMessage(anItem, string.Format("Day value for {0} = {1}", dateString, val));
// Add fixed sum of 18,000 to the day total
val += 18000.00;
AddLogMessage(anItem, string.Format("Adding Fixed Sum of 18,000, day value is now: {0}", val));
// Add the day total to the results table
DataRow row = table.NewRow();
row["Date"] = dateString;
row["Amount"] = val;
table.Rows.Add(row);
}
}
// Find the highest day value in the results table
double max = Convert.ToDouble(table.Compute("max(Amount)", string.Empty));
anItem.result = Math.Round(max, 2);
AddLogMessage(anItem, string.Format("Max value is: {0}", anItem.result));
}
else
AddLogMessage(anItem, string.Format("Bad Parameters for {0}", anItem));
AddLogMessage(anItem, "End of process");
}
Here is the stack trace for the exception:
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at CRLib.CollateralRequiredProcessor.Cr22(RCItem anItem)
at CRLib.CollateralRequiredProcessor.CalculateRequiredCollateral(RCItem anItem)
at CRLib.CollateralRequiredProcessor.Process(String server, String user, String pass, String database, String startDate, String endDate)
at CRUI.frmMain.butProcess_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)