如何响应VSTO Office加载项中的选择更改事件运行后台进程? [英] How to run a background process in response to selection change event in VSTO Office add-in?

查看:116
本文介绍了如何响应VSTO Office加载项中的选择更改事件运行后台进程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an VSTO application-level add-in, with my own custom task pane. I'm trying to intercept the SelectionChange event, and display information in my custom task pane that's relevant to the selection. I do know how to do that synchronously.

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

However the process of fetching the information to display is slow, and I don't want to block the application while I fetch the information. Furthermore, the user may change the selection several times, and I want to cancel any in-progress "fetch" operation if this happens.

我尝试等待长时间运行的操作,但是由于我没有打开表单,所以有

I've tried await-ing the long-running operation, but since I don't have a form open, there is no synchronization context in place, hence I get an InvalidOperationException (cross-thread operation not valid) as soon as I try to update the controls on my task pane.

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

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

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

What's the best way to overcome this? I tried doing as Stephen suggested in the link above, by putting the following at the start of the selection-changed event handler:

SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext())

那没有用.突然我所有其他事件处理程序开始出错,说在创建句柄之前无法调用BeginInvoke".我尝试将相同的代码放在每个事件处理程序的开头,以防万一.那也不起作用.也许我应该创建一个一个 WindowsFormsSynchronizationContext对象并将其用于所有处理程序-但是我知道我现在正在抓紧稻草.

That didn't work. Suddenly all my other event handlers started erroring, saying "BeginInvoke cannot be called until the handle has been created". I tried putting the same code at the start of every event handler, in case it was an all-or-nothing deal. That didn't work either. Perhaps I should have created one WindowsFormsSynchronizationContext object and used it for all the handlers - but I'm aware I'm now clutching at straws.

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

If that doesn't work, what other approaches should I try? Is BeginInvoke still the way to go, or can I jump over to the UI thread some other way?

推荐答案

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

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

这很好奇.我也在抓稻草,但是试试这个:

That's curious. I'm also grasping at straws, but try this:

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

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

instead of calling SynchronizationContext.SetSynchronizationContext directly. You may need to do this at the beginning of each event.

(摘自此博客条目的).

这篇关于如何响应VSTO Office加载项中的选择更改事件运行后台进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆