CalculateUntilAsyncQueriesDone不生效:Excel异步刷新等待问题求助
问题重现代码
var sw = new StopWatch(); sw.Start(); wk.RefreshAll(); wk.Application.CalculateUntilAsyncQueriesDone(); sw.Stop();
问题描述
开发了一个.NET控制台应用,基于Excel模板生成报表。应用会为报表中的查询设置新参数值,并异步刷新连接。这些查询已设置为后台刷新,但发现刷新无法完成,仅在调试时设置断点等待一分钟后才完成。原本认为CalculateUntilAsyncQueriesDone函数会等待异步查询执行完成,查阅Microsoft Learn文档未找到相关解决内容。
解决办法
1. 显式检查并等待所有连接刷新完成
CalculateUntilAsyncQueriesDone可能无法正确识别某些类型的异步查询(比如Power Query或特定OLEDB连接),可以手动遍历所有连接,检查其刷新状态:
wk.RefreshAll(); // 等待所有异步查询完成 bool isRefreshing; do { isRefreshing = false; foreach (var conn in wk.Connections) { if (conn.OLEDBConnection != null && conn.OLEDBConnection.Refreshing) { isRefreshing = true; break; } // 针对Power Query连接的检查 if (conn.ModelConnection != null && conn.ModelConnection.Refreshing) { isRefreshing = true; break; } } if (isRefreshing) { // 每次等待100毫秒,降低CPU占用 System.Threading.Thread.Sleep(100); } } while (isRefreshing); // 确保计算完全完成 wk.Application.CalculateFull();
2. 调整Excel应用的后台配置
控制台环境下可以显式配置Excel应用的异步相关参数,避免状态异常:
var app = wk.Application; // 启用自动计算 app.Calculation = Microsoft.Office.Interop.Excel.XlCalculation.xlCalculationAutomatic; // 确保当前计算状态完成 app.CalculationState = Microsoft.Office.Interop.Excel.XlCalculationState.xlDone; // 允许远程请求(避免后台刷新被阻塞) app.IgnoreRemoteRequests = false;
3. 临时切换为同步刷新
如果不需要保留后台刷新特性,可临时将连接设为同步模式,强制RefreshAll执行完成后再继续:
// 先记录原有设置,后续可恢复 var originalBgSettings = new List<(object Conn, bool IsBg)>(); // 将所有连接设为同步刷新 foreach (var conn in wk.Connections) { if (conn.OLEDBConnection != null) { originalBgSettings.Add((conn, conn.OLEDBConnection.BackgroundQuery)); conn.OLEDBConnection.BackgroundQuery = false; } if (conn.ModelConnection != null) { originalBgSettings.Add((conn, conn.ModelConnection.RefreshInBackground)); conn.ModelConnection.RefreshInBackground = false; } } wk.RefreshAll(); // 恢复原有后台刷新设置(可选) foreach (var (conn, isBg) in originalBgSettings) { var workbookConn = (Microsoft.Office.Interop.Excel.WorkbookConnection)conn; if (workbookConn.OLEDBConnection != null) { workbookConn.OLEDBConnection.BackgroundQuery = isBg; } if (workbookConn.ModelConnection != null) { workbookConn.ModelConnection.RefreshInBackground = isBg; } }
内容的提问来源于stack exchange,提问作者Malcolm
相关产品推荐
相关产品推荐

