我刚刚将我的语言服务从 VS2008 迁移到 VS2010。一切正常,除了一件重要的事情:我不再被LanguageService.ParseSource
调用 for ParseReason.Check
。打开文件后,它确实会获得一次调用。但是在编辑代码后,它不再被调用。
有什么想法可能导致这种情况吗?
我刚刚将我的语言服务从 VS2008 迁移到 VS2010。一切正常,除了一件重要的事情:我不再被LanguageService.ParseSource
调用 for ParseReason.Check
。打开文件后,它确实会获得一次调用。但是在编辑代码后,它不再被调用。
有什么想法可能导致这种情况吗?
当您的Source
对象被初始化时,它以 a LastParseTime
of开始Int32.MaxValue
。导致触发 a ParseRequest
with的代码ParseReason.Check
检查该LastParseTime
值以查看自上次更改文本以来的时间是否小于运行解析所需的时间(或CodeSenseDelay
设置,以较大者为准)。
处理来自的响应的代码ParseSource
应该设置LastParseTime
,但据我所知,它只有在ParseReason
is时才会这样做Check
。
您可以通过设置Source.LastParseTime = 0
初始化Source
. 即使第一次解析尚未完成,这也会产生设置CompletedFirstParse
为的副作用。true
解决此问题的另一种方法是覆盖Source.OnIdle
以触发第一次调用BeginParse()
这是我推荐的方式。
public override void OnIdle(bool periodic)
{
// Once first "Check" parse completes, revert to base implementation
if (this.CompletedFirstParse)
{
base.OnIdle(periodic);
}
// Same as base implementation, except we don't check lastParseTime
else if (!periodic || this.LanguageService == null || this.LanguageService.LastActiveTextView == null || (this.IsCompletorActive) || (!this.IsDirty || this.LanguageService.IsParsing))
{
this.BeginParse();
}
}
我不知道你有没有想过你的问题,但是你有没有试过确保你的 Source 类的 LastParseTime 在创建它时设置为 0?我似乎记得 Check 不会发生的一些问题,除非您在创建 Source 对象时手动将 LastParseTime 设置为 0。
专业提示:如果您使用 .NET Reflector,您可以反汇编 LanguageService 框架的所有基类,并很好地理解它们是如何工作的。您感兴趣的类位于 Microsoft.VisualStudio.Package.LanguageService.10.0.dll 中,应该安装在 GAC 中。当我试图弄清楚为什么事情在我自己的语言服务中不起作用时,我发现这非常有用,并且能够在调试器中单步执行源代码几乎减轻了使用这些框架的所有痛苦!
我还从 2008 年迁移到 2010 年的语言服务。你能检查一下你是否已经完成了所有这些步骤吗?
http://msdn.microsoft.com/en-us/library/dd885475.aspx
我不需要做任何其他事情,我通过在更改前后对比我们仓库中的重要文件来验证这一点。