如何运行后台进程以响应VSTO Office加载项中的选择更改事件



我有一个VSTO应用程序级外接程序,带有我自己的自定义任务窗格。我正在尝试截取SelectionChange事件,并在自定义任务窗格中显示与选择相关的信息。我知道如何同步地做到这一点。

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

我曾尝试等待长时间运行的操作,但由于没有打开表单,因此没有同步上下文,因此在尝试更新任务窗格上的控件时,我会收到InvalidOperationException(跨线程操作无效)。

async void Application_WindowSelectionChange(PowerPoint.Selection selection)
{
var results = await MyLongRunningOperation(cancellationTokenSource.Token);
myControl.Text = DescribeResults(results); // BOOM!
}

克服这种情况的最佳方法是什么?我试着按照Stephen在上面链接中建议的那样做,在选择更改的事件处理程序的开头放上以下内容:

SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext())

那没用。突然,我的所有其他事件处理程序都开始出错,说"在创建句柄之前,不能调用BeginInvoke"。我试着在每个事件处理程序的开头放上相同的代码,以防这是一个要么全有要么全无的交易。这也没用。也许我应该创建一个WindowsFormsSynchronizationContext对象,并将其用于所有处理程序,但我意识到我现在正在抓救命稻草。

如果这不起作用,我还应该尝试其他什么方法?BeginInvoke还有路要走吗?或者我可以以其他方式跳到UI线程吗?

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

这很奇怪。我也在抓救命稻草,但试试这个:

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

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

(想法取自本博客)。

最新更新