2

我有一个 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 线程?

4

1 回答 1

2

突然,我所有的其他事件处理程序都开始出错,说“在创建句柄之前无法调用 BeginInvoke”。

这很好奇。我也抓住了稻草,但试试这个:

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

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

(取自此博客条目的想法)。

于 2012-10-15T16:06:29.357 回答