Языковая служба: ParseReason.Check никогда не вызывается после перехода на VS2010
Я только что перенес свою языковую службу с VS2008 на VS2010. Все отлично работает, кроме одной важной вещи: я больше не получаю LanguageService.ParseSource
призван для ParseReason.Check
, Он действительно получает один вызов после открытия файла. Но после редактирования кода он больше не вызывается.
Есть идеи, что может быть причиной этого?
3 ответа
Я также перенес языковую службу с 2008 по 2010 год. Можете ли вы проверить, выполнили ли вы все эти шаги?
http://msdn.microsoft.com/en-us/library/dd885475.aspx
Мне не нужно было ничего делать, что я проверял, проверяя важные файлы в нашем хранилище до и после изменений.
Я не знаю, разобрались ли вы когда-нибудь со своим вопросом, но пытались ли вы убедиться, что ваш класс Source LastParseTime имеет значение 0 при его создании? Кажется, я вспоминаю некоторые проблемы с проверкой, которая не происходит, если вы вручную не установили LastParseTime в 0 при создании объекта Source.
Подсказка: если вы используете.NET Reflector, вы можете разобрать все базовые классы для среды LanguageService и получить довольно хорошее представление о том, как все это работает под капотом. Классы, которые вас заинтересуют, живут в Microsoft.VisualStudio.Package.LanguageService.10.0.dll, который должен быть установлен в GAC. Я обнаружил, что это невероятно полезно, когда я пытаюсь выяснить, почему что-то не работает в моей собственной языковой службе, и возможность просмотра исходного кода в отладчике уменьшает почти все трудности работы с этими платформами!
Когда ваш Source
объект инициализируется, он начинается с LastParseTime
из Int32.MaxValue
, Код, который вызывает пожары ParseRequest
с ParseReason.Check
проверяет LastParseTime
значение, чтобы увидеть, меньше ли время с момента последнего изменения текста, чем время, необходимое для выполнения анализа (или CodeSenseDelay
настройки, в зависимости от того, что больше).
Код, который обрабатывает ответ от ParseSource
должен установить LastParseTime
, но, насколько я могу судить, он делает это только если ParseReason
является 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();
}
}