2011-04-21 31 views
0

我正在寫一個ASP.NET應用程序,我需要創建多個Excel報告。報告的創建相當耗時(每次最多10秒),所以我使用backgroundworkers同時創建它們。ASP.NET電子表格創建的背景工具:多個互相干擾?

我的代碼看起來有點像這樣:

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工作文件名稱

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   
} 

注:我已經刪除了很多不必要的代碼。如果需要,我可以粘貼它。謝謝

+1

是否在別處使用了'excel_file_name'?而不是分配給它,如果它被刪除(所以防止任何副作用)和文字(例如「NEFT」)直接傳遞給RunWorkerAsync會發生什麼? – 2011-04-21 06:20:00

+0

我想通了這個問題:我傳遞「excel_file_name」作爲參數來創建文件名。但我每次都在改變同一個變量。發生了什麼事,當我打電話給第一個背景工作者時,即使在調用工作人員之前,「excel_file_name」也發生了變化。這導致多個工人的調用具有相同的「excel_file_name」值。現在,我正在使用多個「DoWork」事件,每個事件都有明確定義的文件名,而不是傳遞名稱。我會尋找替代解決方案。謝謝 – 2011-04-21 06:47:26

+0

PS:謝謝你的回答。你對目標感到震驚。太糟糕了我沒有閱讀你的答案之前,花了這麼多時間搞清楚這一點:) 編輯:你知道任何其他方式,我可以將excel_file_name傳遞給RunWorkerAsync?文件名實際上是Datarow的一部分,它也需要傳遞。原始代碼是 dr [5] = name; 和DoWork接受只有一個參數,據我所知 – 2011-04-21 06:48:28

回答

0

最有可能的原因是兩個線程之間的共享狀態 - 共享狀態可能包括excel應用程序和工作簿。所以你需要檢查你的代碼是否一樣。

在附註上,您可以考慮使用一些進程內庫,而不是使用Excel自動生成Excel文件,這可能更具可擴展性並且無法解決此類問題。看看其中一個這樣的free basic library at code project

+0

感謝您的答案VinayC :)然而,我只是想出了什麼問題,併發布作爲這個問題的答案以防萬一有這個困難 – 2011-04-21 06:43:07