Языковая служба: 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();
    }
}
Другие вопросы по тегам