CodeRefactoringProvider заставляет Visual Studio не возвращаться из раздела «Сбор предложений» после получения службы DTE. - PullRequest
0 голосов
/ 23 декабря 2018

Я хочу перечислить файлы текущего проекта из пользовательского CodeRefactoringProvider в проекте Visual Studio 2017 VSIX.Для этого я получаю сервис DTE с Package.GetGlobalService и перебираю решение.Этот код выглядит следующим образом:

[ExportCodeRefactoringProvider( LanguageNames.CSharp, Name = nameof( MyCodeRefactoringProvider ) )]
[Shared]
internal class MyCodeRefactoringProvider : CodeRefactoringProvider {
    public sealed override async Task ComputeRefactoringsAsync( CodeRefactoringContext context ) {
        await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync( cancellationToken );
        DTE dte = (DTE)Package.GetGlobalService( typeof( DTE ) );
        //Enumerate project items...
        return new CodeAction[ 0 ];
    }
}

Я использую JoinableTaskFactory.SwitchToMainThreadAsync для доступа к службе DTE из основного потока, чтобы избежать соответствующего предупреждения.Я могу перечислить файлы и оставить метод ComputeRefactoringsAsync.Когда я пытаюсь открыть всплывающее меню рефакторинга, я получаю сообщение «Сбор предложений», которое постоянно отображается, пока я не нажму Отмена :

Gathering Suggestions

Это на самом деле совершенно не имеет значения, если я на самом деле использую интерфейс DTE или добавляю несколько реальных CodeAction объектов.Достаточно просто получить услугу.

Я попытался исправить проблему безуспешно:

  1. Я удалил вызов на SwitchToMainThreadAsync (и проигнорировал предупреждение).Сообщение по-прежнему отображается.
  2. Я попытался импортировать интерфейс DTE через MEF, который не работает (как объяснено в в этом Q & A )
  3. IЯ попытался перечислить файл проекта в другом потоке, который я начал с JoinableTaskFactory.RunAsync.А затем позвоните JoinAsync на задание.Проблема по-прежнему возникает.
  4. Я попытался вернуться к исходному потоку с await TaskScheduler.Default.Не повезло снова.

Перечисление файлов через CodeRefactoringContext в этом случае не работает, потому что оно содержит только файлы C #, и мне также необходим доступ к файлам других типов.Мне конкретно нужно получить доступ к resx файлам.Через контекст я получаю доступ к исходному файлу, сгенерированному из resx, а не к самому файлу.

Есть ли способ использовать DTE без возникновения этой проблемы?Или есть какой-то другой способ получить доступ к элементам проекта из CodeRefactoringProvider?

...