Application.Wait或Thread.Sleep

时间:2015-04-25 19:21:09

标签: c# multithreading backgroundworker

我已经在使用backgroundworker.RunAsyn()在单独的线程上运行我的代码。但是,我正在尝试在上一行完成之前代码迭代到下一行的部分。我应该创建一个单独的backgroundworker来处理吗?或者我应该使用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)
{

}

3 个答案:

答案 0 :(得分:2)

问题是由于RefreshAll在后台线程上运行引起的。所以基本上你有自己的背景工作者和另一个你没有预料到的人。

refreshAll的文档说: 将BackgroundQuery属性设置为true的对象将在后台刷新。

因此,只有将该属性设置为false,才能解决此问题。然后,refreshall将在你的背景工作者的背景下运行,这就是你的意图。

如果这仍然不起作用,那么你必须重新考虑你的逻辑并寻找在刷新完成时触发的某种事件。如果这不存在,那么除了睡眠之外没有解决方案,但这根本不是一个好的解决方案,因为你不知道睡多久。

答案 1 :(得分: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();

答案 2 :(得分:0)

为什么要延迟某些内容,不能将工作簿保存在SheetCalculate之类的事件上(在重新计算任何工作表之后或在图表上绘制任何更改的数据之后发生)并在您的设置中设置一些标记代码并重置该事件(或任何更相关的事件)