0

我发现了两种在互联网上提供语言服务的方法。

第一种方法IOleComponentManager是在空闲时间使用并注册一个计时器来调用我的服务。

第二种方法涉及将我的服务封装为一个IServiceContainer并添加一个ServiceCreatorCallback以“按需提供服务”。

据说第二种方式现在是做事的“首选方式”。不幸的是,当我使用这种方法时,我的实现OnSynchronizeDropdowns永远不会被调用。TypeAndMembersDropdownBars

此外,当我LanguageService在文件中发现错误时,它会使用ParseRequest.Sink.AddError()将错误添加到错误列表中。当提供“按需”时,这些错误不会显示在 GUI 中,即使我在调试代码时看到它们被添加。

我知道我的语言服务正在注册,因为语法突出显示、“转到定义”和“查找所有参考”仍然有效。

这是我用来“按需提供服务”的代码:

IServiceContainer serviceContainer = this as IServiceContainer;
ServiceCreatorCallback callback = new ServiceCreatorCallback(CreateLanguageService);
serviceContainer.AddService(typeof(MyLanguageService), callback, true);

谁能告诉我为什么我的某些功能LanguageService在按需提供时不起作用?我是否遗漏了什么,或者这种方式不适合功能齐全的语言服务?

4

1 回答 1

1

看起来至少缺少的功能需要使用IOleComponentManager注册计时器的方法来在空闲期间调用语言服务。

使用dotPeek,我发现当您在编辑器中单击时 ,它OnSynchronizeDropdowns()会被调用以同步所选项目。本身似乎只能从该方法调用,我认为这需要使用空闲计时器。OnCaretMoved()OnCaretMoved()LanguageService.OnIdle()

再挖了一些,我也发现错误列表要求ParseRequest.Reason设置为ParseReason.Check,否则忽略调用。进一步挖掘代码,我发现使用解析原因的唯一地方是Source.OnIdle().

更新:我相信我已经确认这两个功能需要注册一个空闲计时器。从 MSDN 上LanguageService.OnIdle

注意 除非您设置自己的计时器并从计时器处理程序调用此方法,否则不会调用此方法。

如果自上次调用OnIdle以来插入符号已移动,则基本方法调用OnCaretMoved。然后基方法调用当前视图的Source对象的 OnIdle 方法。 如果无法获取当前Source对象,则基方法根本不执行任何操作,包括不调用OnCaretMoved

于 2014-02-27T13:44:32.157 回答