我对C#编码还不熟悉,最近我读到最好使用Try Catch
而不是if/else
来处理与文件I / O相关的问题。我还在其他主题中读到,应该在循环中避免使用try catch
块,因为它们会显着降低性能。
就我而言,我正在使用for循环读取多个(通常超过1,000个)excel文件。目前,我正在使用if / else if处理真正的基本异常(即文件是否存在),但我正在考虑实现try catch,原因我上面解释过。
这是我的一些代码
public void ReadFile(string path)
{
Excel.Application xlApp;
Excel.Workbooks xlBooks;
Excel.Workbook xlBook;
Excel.Worksheet xlSheet;
xlApp = new Excel.Application();
xlBooks = xlApp.Workbooks;
xlBook = xlBooks.Open(path);
xlSheet = xlBook.Sheets[1];
int rowCount = FindLastRow(xlSheet);
int colCount = FindLastColumn(xlSheet);
string header = "";
string glNum = Path.GetFileNameWithoutExtension(path).Trim();
for (int row = 1; row <= rowCount; row++)
{
bool processDone = false;
string curationInfo = "";
List<string> data = new List<string>();
// If empty line, skip
if (IsEmpty(xlSheet, row, colCount)) continue;
// If header line, capture
if (IsHeader(xlSheet, row, colCount) != "")
{
header = IsHeader(xlSheet, row, colCount);
continue;
}
// If coloured line, capture
if (IsColoured(xlSheet, row, colCount))
{
curationInfo = ConstructCurationInfo(xlSheet, row, colCount);
data.Add(curationInfo);
// If last row, end
if (row == rowCount) processDone = true;
while (!processDone)
{
// If last row
if (row == rowCount)
{
// If last row is empty, one section is done
if (IsEmpty(xlSheet, row, colCount)) processDone = true;
// If last row is header, one section is done
else if (IsHeader(xlSheet, row, colCount) != "") processDone = true;
// Every other case
else
{
// if coloured, capture
if (IsColoured(xlSheet, row, colCount))
{
string newCurationInfo = ConstructCurationInfo(xlSheet, row, colCount);
data.Add(newCurationInfo);
}
processDone = true;
}
}
// If not last row
else
{
int nextRow = row + 1;
// If next row is last row, end
if (nextRow == rowCount) processDone = true;
// If next row is empty, one section is done
if (IsEmpty(xlSheet, nextRow, colCount)) processDone = true;
// If next row is header, one section is done
else if (IsHeader(xlSheet, nextRow, colCount) != "") processDone = true;
// Every other case
else
{
// if coloured, capture
if (IsColoured(xlSheet, nextRow, colCount))
{
string newCurationInfo = ConstructCurationInfo(xlSheet, nextRow, colCount);
data.Add(newCurationInfo);
}
row++;
}
}
}
}
if (processDone && data.Count != 0)
{
Curation cur = new Curation(header, data, glNum);
curationList.Add(cur);
}
}
// Terminate background Excel Workers
xlBook.Close(false, Missing.Value, Missing.Value);
xlBooks.Close();
xlApp.Quit();
xlApp.DisplayAlerts = false;
Marshal.ReleaseComObject(xlSheet);
Marshal.ReleaseComObject(xlBook);
Marshal.ReleaseComObject(xlBooks);
Marshal.ReleaseComObject(xlApp);
GC.WaitForPendingFinalizers();
GC.Collect();
}
使用ReadFile()方法的Form方法
// Background workers
private void mergeNew_bgw_DoWork(object sender, DoWorkEventArgs e)
{
string input_path = db_input_tb.Text;
string output_dir_path = output_tb.Text;
// Status message to be reported to the UI
string status = "";
status = "Collecting files to be read.....";
mergeNew_bgw.ReportProgress(0, status);
List<string> excelPaths = GetPathToExcel(input_path);
if (IsEmpty(excelPaths))
{
status = "No File to be Processed!";
mergeNew_bgw.ReportProgress(0, status);
fileToProcess = false;
}
// If not empty list, process
else
{
ExcelInfo info = new ExcelInfo();
bool doesExist = false;
string path = "";
int row = 1;
for (int i = 0; i < excelPaths.Count; i++)
{
status = "Processing....." + (i + 1).ToString() + "/" + excelPaths.Count.ToString();
mergeNew_bgw.ReportProgress(0, status);
info.ReadFile(excelPaths[i]);
// If last file, write excel file
if (i + 1 == excelPaths.Count)
{
status = "Writing Complete Merged File";
mergeNew_bgw.ReportProgress(0, status);
info.WriteNew(ref doesExist, ref row, ref path, output_dir_path);
info.Clear();
}
else if ((i + 1) % cutoff == 0)
{
status = "Writing Partial Merged File";
mergeNew_bgw.ReportProgress(0, status);
info.WriteNew(ref doesExist, ref row, ref path, output_dir_path);
info.Clear();
}
}
}
}
我应该在mergeNew_bgw_DoWork方法中的for循环中实现try catch
块吗?
for (int i = 0; i < excelPaths.Count; i++)
{
status = "Processing....." + (i + 1).ToString() + "/" + excelPaths.Count.ToString();
mergeNew_bgw.ReportProgress(0, status);
try
{
info.ReadFile(excelPaths[i]);
}
catch(Exception e)
{
throw new Exception(e.ToString());
}
finally
{
// If last file, write excel file
if (i + 1 == excelPaths.Count)
{
status = "Writing Complete Merged File";
mergeNew_bgw.ReportProgress(0, status);
info.WriteNew(ref doesExist, ref row, ref path, output_dir_path);
info.Clear();
}
else if ((i + 1) % cutoff == 0)
{
status = "Writing Partial Merged File";
mergeNew_bgw.ReportProgress(0, status);
info.WriteNew(ref doesExist, ref row, ref path, output_dir_path);
info.Clear();
}
}
}
感谢您的帮助!
显然,表现不会像其中一条评论所指出的那样改变。但是,我应该在哪里插入try catch块以获得有意义的错误消息? ReadFile()方法很大,所以我认为将整个方法放在try块中可能不会给用户带来意义错误消息。在ReadFile()方法中插入try catch更好吗?