当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在IDE中打开模式对话框时,访问VisualStudioDTE成员将挂起。》经验,为你挑选了0个好方法。

在下面的代码中,我试图访问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();
    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;
  }
}

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

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

推荐阅读
小色米虫_524
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有