我有一个 VSTO 应用程序级加载项,带有我自己的自定义任务窗格。我正在尝试拦截 SelectionChange 事件,并在我的自定义任务窗格中显示与选择相关的信息。我确实知道如何同步进行。
但是,获取要显示的信息的过程很慢,我不想在获取信息时阻止应用程序。此外,用户可能会多次更改选择,如果发生这种情况,我想取消任何正在进行的“获取”操作。
我尝试过等待长时间运行的操作,但由于我没有打开表单,因此没有同步上下文,因此我一尝试就得到 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 线程?