2015-04-25 24 views
1

我已經使用backgroundworker.RunAsyn()在單獨的線程上運行我的代碼。不過,我在上一行完成之前觸及代碼迭代到下一行的部分。我應該創建一個單獨的backgroundworker來處理?或者我應該使用Application.Wait()還是Thread.Sleep()我不確定拖延的時間,我寧願不讓我的程序坐在等待額外的不需要的時間,所以我不確定要採取哪條路線。這是一個麻煩製造者的片段。Application.Wait或Thread.Sleep

public Form_Main() 
{ 
    InitializeComponent(); 
    backgroundworker1.WorkerReportsProgress = true; 
    backgroundworker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); 
    backgroundWorker1_ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged); 
} 

private void btnOpenRefreshSave_Click() 
{ 
    backgroundWorker1_RunWorkerAsync(); 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    Excel.Application exApp; 
    Excel._Workbook exBook; 
    Excel._Worksheet exSheet; 

    exBook = (Excel._Workbook)(exApp.WOrkbooks.Open("C:\\Book1.xlsx")); 
    exSheet = (Excel._Worksheet)(exBook.ActiveSheet); 
    //This is the line of code that often times takes a while 
    exBook.RefreshAll(); 
    //end of trouble line 
    exBook.SaveAs("C:\\Updated_Book1.xlsx"); 
} 

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 

} 
+0

你是什麼意思的「代碼迭代到前一行完成之前的下一行」? –

+0

@SriramSakthivel它將在刷新操作有時間完成之前保存工作簿。 –

+0

請參考[this](http://stackoverflow.com/questions/8925403/excel-vba-refresh-wait)和[this](http://stackoverflow.com/questions/18788384/wait-for-workbook-refreshall -c) –

回答

2

在這裏做什麼時會想到幾件事情。你可以嘗試使用類似於下面的東西

if (Application.CalculationState === xlDone Then 
    everything is finished calculating[enter link description here][1] 

另一種選擇是(如其他人所建議的)改變背景刷新屬性。對工作簿的快速掃描可以以編程方式更改爲您

foreach (Wrksheet ws in workbook.wss) 
{ 
    foreach (QueryTable table in ws.QueryTables) 
     table.BackgroundQuery = false; 
} 
workbook.RefreshAll(); 
0

你爲什麼要延遲一些東西,你就不能在它的活動,如SheetCalculate(任何表重新計算或之後發生之後的任何更改的數據繪製在圖表上),並設置一個保存工作簿代碼中的一些標誌,並重置該事件(或任何更相關的事件)

+0

我從來沒有使用過SheetCalculate,你能提供一個如何做這樣的例子嗎? –

2

該問題是由於RefreshAll在後臺線程上運行引起的。所以基本上你有自己的背景工作者在跑,另一個你沒有預料到。

refreshAll的文檔說: BackgroundQuery屬性設置爲true的對象在後臺刷新。

所以你可以擺脫這個問題只是將該屬性設置爲false。然後refreshall會運行在你的背景工作者的背景下,這就是你的意圖。

如果這仍然不起作用,那麼您必須重新考慮您的邏輯並查找刷新完成時觸發的某種事件。如果這不存在,那麼除了睡眠之外沒有其他解決方案,但這根本不是一個好的解決方案,因爲你不知道睡多久。

+0

能夠將所有內容都更改爲enablebackgroundrefresh = false是不現實的。所以我認爲我會被卡住,不得不像使用Thread.Sleep()一樣鄙視它。 –