【问题标题】:ASP.NET Backgroundworkers for spreadsheet creation: multiple ones interfering with each other?用于电子表格创建的 ASP.NET Backgroundworkers:多个相互干扰?
【发布时间】:2011-04-21 06:02:16
【问题描述】:

我正在编写一个 ASP.NET 应用程序,我需要在其中创建多个 Excel 报表。报告创建非常耗时(每个报告最多十秒),所以我使用后台工作人员同时创建它们。

我的代码看起来有点像这样:

if (condition1)

{
excel_file_name = "TRANSFER";
BackgroundWorker worker_t = new BackgroundWorker();
worker_t.DoWork += new DoWorkEventHandler(DoWork);
worker_t.WorkerReportsProgress = false;
worker_t.WorkerSupportsCancellation = true;
worker_t.RunWorkerCompleted +=
                       new RunWorkerCompletedEventHandler(WorkerCompleted);
worker_t.RunWorkerAsync(excel_file_name);
}

if (Condition2)
{
excel_file_name = "NEFT";
BackgroundWorker worker_n = new BackgroundWorker();
worker_n.DoWork += new DoWorkEventHandler(DoWork);
worker_n.WorkerReportsProgress = false;
worker_n.WorkerSupportsCancellation = true;
worker_n.RunWorkerCompleted +=
                       new RunWorkerCompletedEventHandler(WorkerCompleted);
worker_n.RunWorkerAsync(excel_file_name);
}

还有更多条件,但我没有写它们,因为它们都是相似的。唯一的区别是 Excel_File_Name

DoWork 甚至会调用一个类来创建具有给定名称的 excel 文件。

当条件 1 和条件 2 都为真时,问题如下: 1. 如果我在调试期间使用断点缓慢运行,则会创建两个文件(TRANSFER 和 NEFT)。 2. 但是,如果我像普通应用程序那样在没有断点的情况下运行它,则只会创建最后一个文件(本例中为 NEFT)。

可能是什么问题?

谢谢

PS:有关更多信息,以下是创建 excel 文件的类中的重要代码:

private static string placeDataInTemplate(string destFilePath, DataRow dr, bool isCoverLetter)
    {
        int loop = 0;
        ExcelNamespace.Application excelApplication = new ExcelNamespace.Application();

        ExcelNamespace.Workbook workbook = excelApplication.Workbooks.Open(destFilePath, 0, false, 5,
          "", "", true, ExcelNamespace.XlPlatform.xlWindows, "\t", false, false, 0, true, true, false);
        ExcelNamespace.Worksheet workSheet = (ExcelNamespace.Worksheet)workbook.Sheets[sheet_no];

        try
        {
            string value;
            string replicate;
            string replicate_end;

            // get data for Place Holders
            sDataTable dtPlaceHolderData = getPlaceHolderData(dr);

                           //make Display Alerts False
                excelApplication.DisplayAlerts = false;


            if (dtPlaceHolderData != null && dtPlaceHolderData.Rows.Count > 0)
            {

                int rowCntDt = 0; //Which row will be used for data?
                int i = 1;
                Excel.Range Find = (ExcelNamespace.Range)workSheet.Cells.Find("#",
                        (ExcelNamespace.Range)workSheet.Cells[1, 1],
                        Excel.XlFindLookIn.xlValues,
                        Excel.XlLookAt.xlPart,
                        Excel.XlSearchOrder.xlByRows,
                        Excel.XlSearchDirection.xlNext,
                        false,
                        false,
                        Missing.Value);

                while (Find != null && loop <= 200)
                {
                    loop++;
                    value = Find.Value2.ToString();

                    if (condition)
                    //VERY long if...else if

                 }

                string approveDirPath = destFilePath.Replace(Path.GetFileName(destFilePath), string.Empty);
                workbook.Close(true, destFilePath, Type.Missing);
                excelApplication.Quit();
                string filepath = destFilePath.Split('-')[0];
                string approval_id = dr[0].ToString();
                return destFilePath;
            }
 return string.Empty;
        }
        catch (Exception ex)
        {
            //do something        
}
            finally
            {
                //release resources        
}

注意:我删除了很多不必要的代码。如果需要,我可以粘贴它。谢谢

【问题讨论】:

  • excel_file_name 是否在其他地方使用过?如果将其删除(以防止任何副作用)并且将文字(例如“NEFT”)直接传递给 RunWorkerAsync,而不是分配给它,会发生什么?
  • 我发现了问题:我将“excel_file_name”作为参数传递来创建文件名。但我每次都在改变同一个变量。发生的事情是,当我调用第一个后​​台工作者时,“excel_file_name”甚至在调用工作者之前就已更改。这导致调用具有相同值的“excel_file_name”的多个工作者。现在,我正在使用多个“DoWork”事件,每个事件都明确​​定义了文件名,而不是传递名称。我将为此寻找替代解决方案。谢谢
  • PS:感谢 pst,您的回答。你正中目标。太糟糕了,在花了这么多时间弄清楚之前我没有阅读你的答案:) 编辑:你知道我可以将 excel_file_name 传递给 RunWorkerAsync 的任何其他方式吗?文件名实际上是 Datarow 的一部分,也需要传递。原始代码是 dr[5] = name;据我所知,DoWork 只接受一个参数

标签: asp.net backgroundworker export-to-excel


【解决方案1】:

最可能的原因是两个线程之间的某些共享状态 - 共享状态可能包括 Excel 应用程序和工作簿。所以你需要检查你的代码是否相同。

附带说明,您可以考虑使用一些进程内库,而不是使用 Excel 自动化生成 excel 文件,这可能更具可扩展性并且不会出现此类问题。看看这样的free basic library at code project

【讨论】:

  • 感谢 VinayC 的回答 :) 不过,我只是想出了问题所在,我将其发布为对这个问题的回答,以防其他人遇到这种困难
猜你喜欢
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-27
  • 1970-01-01
  • 2019-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多