private void ClearControlCharactersFromCategory(string categoryName, bool doCommit) { using (var db = new CommenceDatabase()) using (var cur = db.GetCursor(categoryName, CmcCursorType.Category, CmcOptionFlags.UseThids)) { rules = GetReplacementRulesForCategory(this.CategoryName); // use the keys in rules to limit our cursor // the keys represent the fieldnames to be processed cur.Columns.AddDirectColumns(rules.Keys.ToArray()); cur.Columns.Apply(); int totalRows = cur.RowCount; changeLog.DatabaseName = db.Name; for (int rows = 0; rows < totalRows; rows += maxRows) { using (var ers = cur.GetEditRowSet(maxRows)) { int rowCount = ers.RowCount; var rowsetIsDirty = ProcessRows(ers, rowCount); if (doCommit && rowsetIsDirty) { int result = ers.Commit(); if (result != 0) // database write failed { try { changeLog.WriteToFile(logFile); } finally { throw new CommenceCOMException($"Commit method failed on rowset between rows {rows} and {rows + rowCount}."); } } } // explicitly close rowset, even though it will be closed automatically. // it is just a safety precaution to prevent Commence // running out of resources before GC kicks in. ers.Close(); } if (rows % 100 == 0) { WriteProgress(new ProgressRecord(0, $"{rows} of {totalRows} ({this.CategoryName})", $"Commence rows processed.")); } } changeLog.WriteToFile(logFile); // all went peachy } }