在IDE中打开模式对话框时,访问Visual Studio DTE成员将挂起。

Erw*_*yer 5 c# debugging hang visual-studio envdte

在下面的代码中,我试图访问Debugger一个有效DTE2对象的属性(通过类似于方法的方法获得),以检查它是否正在调试当前进程(可能会打开多个Visual Studio实例)。

它工作正常,但当一个Visual Studio(2015)实例显示一个模式对话框时(例如,询问是否应由于后台代码更改而重新加载当前加载的项目的源代码),访问dte.Debugger将一直挂起,直到出现对话框由用户处理。尝试访问该dte对象的其他成员也将挂起。

using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Threading;
using EnvDTE;
using EnvDTE80;
using EnvDTE90a;

public static class VSAutomation {
  public static int? GetCurrentDebuggerPid() {
    var taskCompletion = new TaskCompletionSource<int?>();
    var staThread = new System.Threading.Thread(() => {
      try {
        int? debuggerPid = null;
        using (new MessageFilter()) {
          using (var currentProcess = System.Diagnostics.Process.GetCurrentProcess())
          using (var vsInstances = System.Diagnostics.Process.GetProcessesByName("devenv").AsDisposable()) {
            foreach (var p in vsInstances.Enumerable) {
              DTE2 dte;
              if (TryGetVSInstance(p.Id, out dte)) {
                Utils.Retry(() => {
                  var debugger = dte.Debugger; //MAY HANG HERE
                  if (debugger != null) {
                    foreach (Process2 process in debugger.DebuggedProcesses) {
                      if (process.ProcessID == currentProcess.Id) {
                        debuggerPid = p.Id;
                        break;
                      }
                    }
                  }
                  Marshal.ReleaseComObject(dte);
                }, nbRetries: int.MaxValue, msInterval: 1000, retryOnlyOnExceptionTypes: typeof(COMException).InArray());
                if (debuggerPid != null) break;
              }
            }
          }
        }
        taskCompletion.SetResult(debuggerPid);
      }
      catch (Exception ex) {
        taskCompletion.TrySetException(ex);
      }
    }) { IsBackground = true };
    staThread.SetApartmentState(ApartmentState.STA);
    staThread.Start();
    taskCompletion.Task.Wait();
    return taskCompletion.Task.Result;
  }
}
Run Code Online (Sandbox Code Playgroud)

Debugger尽管打开了模式对话框,是否有任何访问对象的方法?

如果不是,除了var debugger = dte.Debugger在具有超时的任务中启动任务之外,是否有其他方法可以检测到需要执行用户操作?