【问题标题】:Application.Wait or Thread.SleepApplication.Wait 或 Thread.Sleep
【发布时间】:2015-04-25 19:21:08
【问题描述】:

我已经在使用backgroundworker.RunAsyn() 在单独的线程上运行我的代码。但是,我遇到了在上一行完成之前代码迭代到下一行的部分。我应该创建一个单独的backgroundworker 来处理它吗?或者我应该使用Application.Wait()Thread.Sleep() 我不确定要延迟多少时间,我宁愿让我的程序不坐在那里等待额外的不必要的时间,所以我不确定要走哪条路。这是麻烦制造者的sn-p。

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)
{

}

【问题讨论】:

  • “代码在上一行完成之前迭代到下一行”是什么意思?
  • @SriramSakthivel 它将在刷新操作有时间完成之前保存工作簿。
  • 参考thisthis
  • RefreshAll 是同步的,因此您无需做任何其他事情...
  • @AdrianoRepetti 文档says something different。我对文档的看法是对的吗?

标签: c# multithreading backgroundworker


【解决方案1】:

想到这里做什么。您可以尝试使用类似于以下的内容

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】:

    问题是因为 RefreshAll 在后台线程上运行引起的。所以基本上你有自己的后台工作人员在运行,另一个你没有预料到。

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

    因此,您只需将该属性设置为 false 即可解决此问题。然后刷新将在您的后台工作人员的上下文中运行,这就是您的意图。

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

    【讨论】:

    • 能够将所有内容更改为 enablebackgroundrefresh = false 对我来说是不现实的。所以我认为我将不得不使用 Thread.Sleep() ,尽管我很鄙视它。
    【解决方案3】:

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

    【讨论】:

    • 我从来没有用过SheetCalculate,你能举个例子吗?
    猜你喜欢
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    • 2017-09-30
    • 1970-01-01
    • 2014-02-18
    • 1970-01-01
    • 2010-11-27
    相关资源
    最近更新 更多