我正在编写一个程序,它涉及将Excel文件重度转换为非常特殊格式的平面文件。有超过50,000行需要转换,所以不用说,处理需要一段时间。
话虽如此,使用BackgroundWorker
最有意义。
我所做的一切都正常执行并且工作正常除了一个问题:尝试从实例化的类中调用BackgroundWorker.ReportProgress()
方法来更新父Form
上的计数器。
如果我没有意义,也许我的代码会更有意义:
处理GUI表单:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
namespace CityTaxImport
{
public partial class Processing : Form
{
string s_sourceFile;
bool b_fileSaved;
CityConvert convert = new CityConvert();
public Processing(string s_incomingPath)
{
BackgroundWorker bg_Taxes = new BackgroundWorker();
s_sourceFile = s_incomingPath;
//background worker
bg_Taxes.DoWork += new DoWorkEventHandler(bg_Taxes_DoWork);
bg_Taxes.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_Taxes_RunWorkerCompleted);
bg_Taxes.ProgressChanged += new ProgressChangedEventHandler(bg_Taxes_ProgressChanged);
bg_Taxes.WorkerSupportsCancellation = true;
bg_Taxes.WorkerReportsProgress = true;
InitializeComponent();
bg_Taxes.RunWorkerAsync();
}
#region METHODS
#region BACKGROUND WORKER
//do work/runworker Async stuff
private void bg_Taxes_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bg_Taxes = sender as BackgroundWorker;
CityConvert convert = new CityConvert();
convert.ConvertFile(s_sourceFile);
}
//when the worker completes, let user know, end program
private void bg_Taxes_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pb_Progress.MarqueeAnimationSpeed = 0;
//lets the user know the file is done and prompts them on where to save it at
if (MessageBox.Show(this, "The file has been created.\nChoose where you would like to save it.",
"Conversion Finished", MessageBoxButtons.OK, MessageBoxIcon.Asterisk) == DialogResult.OK)
{
while (b_fileSaved != true)
{
SaveFile();
}
}
}
//used to update the progress count
public void bg_Taxes_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//RIGHT HERE IS WHAT SHOULD UPDATE THE COUNTER
lb_recordCount.Text = convert.i_RowCount.ToString();
}
#endregion
现在班上有所有的辛苦工作:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.IO;
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace CityTaxImport
{
class CityConvert
{
#region VARIABLES AND OBJECTS AND ALL THE OTHER VARS AND CHARS
//the Excel squad
Excel._Application xl_app;
Excel._Workbook xl_wrkBk;
Excel._Worksheet xl_wrkSht;
//our friend object Type.Missing
private object o_miss = Type.Missing;
//dataset and table
private DataSet ds_taxes;
private DataTable dt_taxes;
private DataRow dr_taxes;
//strings and counts and stuff
private string s_sourceFile;
private int i_xlRowTotal;
private int i_xlRowCount;
private int i_dtRowCount;
private string s_output;
public int i_RowCount{get; set;}
#endregion
#region METHODS
//the initial convert file method called by the main window
public bool ConvertFile(string s_selectedFile)
{
s_sourceFile = s_selectedFile;
CreateDataSet();
OpenExcel();
PopulateDateSet();
WriteFile();
CloseExcel();
return true;
}
//builds the dataset to use
//creates the column names that will be written into and then written to the flat file
//SOME WILL JUST BE SPACES
private void CreateDataSet()
{
ds_taxes = new DataSet();
ds_taxes.Tables.Add("Taxes");
dt_taxes = new DataTable();
dt_taxes = ds_taxes.Tables["Taxes"];
dt_taxes.Columns.Add("Pr_Ward");
dt_taxes.Columns.Add("Pr_Block");
dt_taxes.Columns.Add("Pr_Map");
dt_taxes.Columns.Add("Pr_Parcel");
dt_taxes.Columns.Add("Pr_LeaseHold");
dt_taxes.Columns.Add("ParFill");
dt_taxes.Columns.Add("Stub");
dt_taxes.Columns.Add("Pa_Amt");
dt_taxes.Columns.Add("TOTFLG");
dt_taxes.Columns.Add("Pr_WardBATCH");
dt_taxes.Columns.Add("BSEQ");
dt_taxes.Columns.Add("TRANSNO");
dt_taxes.Columns.Add("TRANCD");
dt_taxes.Columns.Add("Pa_BatchDate_TD");
dt_taxes.Columns.Add("Pa_BatchDate_ED");
dt_taxes.Columns.Add("BUSDATE");
dt_taxes.Columns.Add("METH");
dt_taxes.Columns.Add("Pa_Amt2");
dt_taxes.Columns.Add("Payment_ID");
dt_taxes.Columns.Add("OWNSEQ");
dt_taxes.Columns.Add("Pr_OwnerInfo1");
}
//time to populate the dataset form the info from the ExcelSheet
private void PopulateDateSet()
{
//
i_xlRowTotal = 2;
while (xl_wrkSht.Cells.Range["A" + i_xlRowTotal].Value2 != null)
{
i_xlRowTotal++;
}
i_xlRowCount = 2;
i_xlRowTotal = i_xlRowTotal - 2;
for (i_dtRowCount = 0; i_dtRowCount < (i_xlRowTotal); ++i_dtRowCount)
{
//this is used to make conversions of the strings to add paddings, length modifiers, what have you...
//all that fun stuff
dr_taxes = dt_taxes.NewRow();
dr_taxes["Pr_Ward"] = Convert.ToString(xl_wrkSht.Cells.Cells.Range["P" + (i_xlRowCount)].Value2);
dr_taxes["Pr_Block"] = Convert.ToString(xl_wrkSht.Cells.Range["Q" + (i_xlRowCount)].Value2);
dr_taxes["Pr_Map"] = Convert.ToString(xl_wrkSht.Cells.Range["R" + (i_xlRowCount)].Value2);
dr_taxes["Pr_Parcel"] = Convert.ToString(xl_wrkSht.Cells.Range["S" + (i_xlRowCount)].Value2);
dr_taxes["Pr_LeaseHold"] = Convert.ToString(xl_wrkSht.Cells.Range["T" + (i_xlRowCount)].Value2);
dr_taxes["ParFill"] = @" ";//12 spaces
dr_taxes["Stub"] = @" ";//10 spaces ALWAYS
dr_taxes["Pa_Amt"] = AppendAmt();
dr_taxes["TOTFLG"] = "N";
dr_taxes["Pr_WardBATCH"] = AppendWard();
dr_taxes["BSEQ"] = AppendBSEQ();
dr_taxes["TRANSNO"] = "000000000";
dr_taxes["TRANCD"] = "P";
dr_taxes["Pa_BatchDate_TD"] = AppendBatchDates();
dr_taxes["Pa_BatchDate_ED"] = AppendBatchDates();
dr_taxes["BUSDATE"] = @" "; //6 spaces
dr_taxes["METH"] = "Check";
dr_taxes["Pa_Amt2"] = AppendAmt();
dr_taxes["Payment_ID"] = AppendID();
dr_taxes["OWNSEQ"] = "000";
dr_taxes["Pr_OwnerInfo1"] = AppendOwner();
dt_taxes.Rows.Add(dr_taxes);
++i_xlRowCount;
i_RowCount = i_xlRowCount;
//RIGHT HERE IS WHERE I WANT TO CALL THE
Processing.bg_Taxes.ReportProgress() //method
}
}
我尝试了Processing.bg_Taxes.ReportProgress();
,但我收到Object reference is required for the non-static...method
错误(我明白这是错误的。)
我还看了很多其他Q&amp;在这里关于使用BackgroundWorkers
然而他们似乎没有完全回答我的问题或我只是没有得到它(这可能也是问题)。
我的问题是:有没有办法在不使BackgroundWorker
静态的情况下调用该方法?
有了这个:将它变为静态是否存在任何问题(我总是被告知避免静态方法以及编写代码时有什么用)。
最后:我在这里的逻辑中遗漏了一些关于我应该怎么做的事情?还有另外一种“最佳实践”方式吗?
感谢任何帮助或建议。
提前谢谢大家。
更新
我最后通过一些基本方法解决了我的问题,然后改变了我的代码。只是想把它扔出去,感谢大家指点我正确的方向。