c# - 如何运行后台进程来响应 VSTO Office 加载项中的选择更改事件?

标签 c# vsto async-await

我有一个 VSTO 应用程序级加载项,带有我自己的自定义任务 Pane 。我试图拦截 SelectionChange 事件,并在自定义任务 Pane 中显示与选择相关的信息。我确实知道如何同步执行此操作。

但是,获取要显示的信息的过程很慢,并且我不想在获取信息时阻止应用程序。此外,用户可能会多次更改选择,如果发生这种情况,我想取消任何正在进行的“获取”操作。

我尝试等待长时间运行的操作,但由于我没有打开表单,所以有 no synchronization context in place ,因此当我尝试更新任务 Pane 上的控件时,我会收到 InvalidOperationException(跨线程操作无效)。

async void Application_WindowSelectionChange(PowerPoint.Selection selection)
{
    var results = await MyLongRunningOperation(cancellationTokenSource.Token);

    myControl.Text = DescribeResults(results); // BOOM!
}

克服这个问题的最佳方法是什么?我尝试按照上面链接中斯蒂芬的建议进行操作,将以下内容放在选择更改事件处理程序的开头:

SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext())

那没用。突然,我的所有其他事件处理程序开始出错,显示“在创建句柄之前无法调用 BeginInvoke”。我尝试将相同的代码放在每个事件处理程序的开头,以防这是一个全有或全无的交易。那也没用。也许我应该创建一个 WindowsFormsSynchronizationContext 对象并将其用于所有处理程序 - 但我知道我现在捕获了救命稻草。

如果这不起作用,我应该尝试其他哪些方法? BeginInvoke 仍然是可行的方法吗,或者我可以通过其他方式跳转到 UI 线程吗?

最佳答案

Suddenly all my other event handlers started erroring, saying "BeginInvoke cannot be called until the handle has been created".

这很好奇。我也在捕获救命稻草,但试试这个:

Control control = new Control();
IntPtr handle = control.Handle;

而不是直接调用SynchronizationContext.SetSynchronizationContext。您可能需要在每个事件开始时执行此操作。

(想法取自 this blog entry )。

关于c# - 如何运行后台进程来响应 VSTO Office 加载项中的选择更改事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12898569/

相关文章:

c# - 命令完成后获取命令提示符窗口内容

c# - 在 C# 中读取视频元数据

c# - 用户编辑后数据网格单元格格式不保留?

c# - "Microsoft Office Developer Tools"和 "Visual Studio Tools for Office"有什么区别

c#:以编程方式在工作表范围内创建 "named range"

c# - 如何等待 Observable 的 Observable?

c# - CancellationToken 注销操作

async-await - 将 next.js 配置为使用 Babel 不转换异步函数

c# - 如何防止其他应用程序窃取焦点?

c# - 使用正确的列宽和格式从 DataSet 加载 DataTable