VS2010Datatable查看器查看超时(Microsoft.VisualStudio.DebuggerVisualizers)

  这个问题由来已久,却一直没有找到原因。大家都知道,VisualStudio的DebuggerVisualizers是一个非常方便的插件,可以帮助我们调试时查看Datatable视图,前阵子突然发现在查看时报错了,截图 如下:

VS2010Datatable查看器查看超时(Microsoft.VisualStudio.DebuggerVisualizers)

  详细信息里的内容是:

 1 有关调用实时(JIT)调试而不是此对话框的详细信息,

 2 请参见此消息的结尾。

 3 

 4 ************** 异常文本 **************

 5 System.Exception: 函数计算超时。

 6    在 Microsoft.VisualStudio.DebuggerVisualizers.DebugViewerShim.PrivateCallback.MaybeDeserializeAndThrowException(Byte[] data)

 7    在 Microsoft.VisualStudio.DebuggerVisualizers.DebugViewerShim.ManagedShim.DelegatedHost.CreateViewer(IntPtr hwnd, HostServicesHelper hsh, SafeProxyWrapper proxy)

 8 

 9 

10 ************** 已加载的程序集 **************

11 mscorlib

12     程序集版本:4.0.0.0

13     Win32 版本:4.0.30319.18444 built by: FX451RTMGDR

14     基本代码:file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll

15 ----------------------------------------

16 Microsoft.VisualStudio.Platform.AppDomainManager

17     程序集版本:12.0.0.0

18     Win32 版本:12.0.21005.1

19     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Microsoft.VisualStudio.Platform.AppDomainManager/v4.0_12.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Platform.AppDomainManager.dll

20 ----------------------------------------

21 System

22     程序集版本:4.0.0.0

23     Win32 版本:4.0.30319.18408 built by: FX451RTMGREL

24     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll

25 ----------------------------------------

26 System.Configuration

27     程序集版本:4.0.0.0

28     Win32 版本:4.0.30319.18408 built by: FX451RTMGREL

29     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll

30 ----------------------------------------

31 System.Xml

32     程序集版本:4.0.0.0

33     Win32 版本:4.0.30319.34234 built by: FX452RTMGDR

34     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll

35 ----------------------------------------

36 System.Windows.Forms

37     程序集版本:4.0.0.0

38     Win32 版本:4.0.30319.18408 built by: FX451RTMGREL

39     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll

40 ----------------------------------------

41 System.Drawing

42     程序集版本:4.0.0.0

43     Win32 版本:4.0.30319.18408 built by: FX451RTMGREL

44     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll

45 ----------------------------------------

46 Microsoft.VisualStudio.DebuggerVisualizers

47     程序集版本:12.0.0.0

48     Win32 版本:12.0.21005.1

49     基本代码:file:///C:/Windows/assembly/GAC_MSIL/Microsoft.VisualStudio.DebuggerVisualizers/12.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.DebuggerVisualizers.dll

50 ----------------------------------------

51 System.Windows.Forms.resources

52     程序集版本:4.0.0.0

53     Win32 版本:4.0.30319.18408 built by: FX451RTMGREL

54     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms.resources/v4.0_4.0.0.0_zh-Hans_b77a5c561934e089/System.Windows.Forms.resources.dll

55 ----------------------------------------

56 

57 ************** JIT 调试 **************

58 要启用实时(JIT)调试,

59 该应用程序或计算机的 .config 文件(machine.config)的 system.windows.forms 节中必须设置

60 jitDebugging 值。

61 编译应用程序时还必须启用

62 调试。

63 

64 例如:

65 

66 <configuration>

67     <system.windows.forms jitDebugging="true" />

68 </configuration>

69 

70 启用 JIT 调试后,任何未经处理的异常

71 都将被发送到在此计算机上注册的 JIT 调试器,

72 而不是由此对话框处理。
View Code

  从这个错误内容来看,最后抛出的是行6和行7,这是IDE绘制查看器弹窗时抛出的异常,我找了下这个dll,还真找到了,具体位置在

Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.VisualStudio.DebuggerVisualizers.dll

  当然,VS真正调的应该不是这个位置,从错误行49可以看出(实际上把这个位置的DebuggerVisualizers.dll删除照样可以使用),是调的Windows下面的某个位置,这可能是写到注册表里或者环境变量里了,反正是这个dll不错,但是vs使用的位置我没法查到。用Reflector反编译之,行7的CreateViewer源码如下:

 1 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine), ResourceExposure(ResourceScope.None)]

 2 internal void CreateViewer(IntPtr hwnd, ManagedShim.HostServicesHelper hsh, ManagedShim.SafeProxyWrapper proxy)

 3 {

 4     try

 5     {

 6         byte[] data = proxy.InitSourceDataProvider();

 7         using (AssemblyResolver resolver = new HostResolver(proxy, hsh.IsRemote, new ServiceProvider.WindowWrapper(hwnd)))

 8         {

 9             string str;

10             string str2;

11             int num;

12             ASSEMBLYLOCRESOLUTION assemblylocresolution;

13             byte[] buffer;

14             byte[] buffer2;

15             PrivateCallback.MaybeDeserializeAndThrowException(data);

16             proxy.GetManagedViewerCreationData(out str, out buffer, out buffer2, out str2, out assemblylocresolution, out num);

17             if ((assemblylocresolution == ASSEMBLYLOCRESOLUTION.ALR_ERROR) && (str != null))

18             {

19                 throw new TerminalException(str, MessageBoxIcon.Hand);

20             }

21             if (((buffer != null) && (str == null)) && (hsh.IsRemote && !QueryRemoteLoadAllowed(null, new ServiceProvider.WindowWrapper(hwnd))))

22             {

23                 throw new TerminalException(MessageBoxIcon.Hand);

24             }

25             ClassAndAssemblySpec spec = new ClassAndAssemblySpec(str, buffer, assemblylocresolution != ASSEMBLYLOCRESOLUTION.ALR_NAME, str2);

26             DialogDebuggerVisualizer visualizer = (DialogDebuggerVisualizer) spec.CreateInstance(resolver);

27             using (PrivateCallback callback = new PrivateCallback(proxy, num != 0))

28             {

29                 visualizer.Show(new ServiceProvider(hwnd, hsh).DialogService, callback);

30             }

31         }

32     }

33     catch (TerminalException exception)

34     {

35         exception.DisplayDialog(new ServiceProvider.WindowWrapper(hwnd));

36     }

37     catch (Exception exception2)

38     {

39         new ThreadExceptionDialog(exception2).ShowDialog(new ServiceProvider.WindowWrapper(hwnd));

40     }

41 }
View Code

  从上面可以看出,走到行15就执行了异常处理,然后由PrivateCallback的MaybeDeserializeAndThrowException方法接管过来,MaybeDeserializeAndThrowException源码如下:

 1 internal static unsafe byte[] MaybeDeserializeAndThrowException(byte[] data)

 2 {

 3     if ((data == null) || (data.Length == 0))

 4     {

 5         return null;

 6     }

 7     DebugeeHost.DataPrefix prefix = (DebugeeHost.DataPrefix) data[0];

 8     switch (prefix)

 9     {

10         case DebugeeHost.DataPrefix.Exception:

11         {

12             Exception exception = (Exception) DeserializeObject(data, 1);

13             throw exception;

14         }

15         case DebugeeHost.DataPrefix.ObjectData:

16             return data;

17 

18         case DebugeeHost.DataPrefix.CustomExceptionData:

19         {

20             DebugeeHost.CustomExceptionDataHolder cedh = (DebugeeHost.CustomExceptionDataHolder) DeserializeObject(data, 1);

21             throw new RemoteObjectSourceException(cedh);

22         }

23         case DebugeeHost.DataPrefix.ErrorString:

24         case DebugeeHost.DataPrefix.ErrorStringNoHost:

25             if (data.Length < 8)

26             {

27                 throw new ApplicationException(SR.GetString("E_G_InvalidSerializationFormat"));

28             }

29             break;

30 

31         default:

32             return data;

33     }

34     fixed (byte* numRef = data)

35     {

36         int length = numRef[4];

37         if ((data.Length - 8) < (length * 2))

38         {

39             throw new ApplicationException(SR.GetString("E_G_InvalidSerializationFormat"));

40         }

41         char* chPtr = (char*) (numRef + 8);

42         string message = new string(chPtr, 0, length);

43         if (prefix == DebugeeHost.DataPrefix.ErrorStringNoHost)

44         {

45             throw new TerminalException(message, MessageBoxIcon.Exclamation);

46         }

47         throw new Exception(message);

48     }

49 }
View Code

  这里应该就是最后的“事发现场了”,其中case的枚举如下:

1 internal enum DataPrefix : byte

2 {

3     CustomExceptionData = 3,

4     ErrorString = 4,

5     ErrorStringNoHost = 5,

6     Exception = 1,

7     ObjectData = 2

8 }
View Code

  到此好像没法追踪下去了,它是通过传入的byte[]的0位值来抛出相应的异常,只有值为2或者default的时候才不抛出,由于没法模拟环境,即使我给了传入byte[],那么里面的调用层次还是要经过一番考究的。为此我也考虑了其他因素:

  1. 系统

  2. 硬件

  3. 内存

  4. 杀毒软件

  5. IDE本身

  6. 软件冲突

  7. 补丁

  8. IDE配置

  现在的现象是时好时坏,那么2、7就可以排除了,找了另外一台电脑,同样的系统同样的vs版本可以查看,那么1和5可以排除,内存用360释放一样有错,3可以排除,杀毒软件退掉依旧,4可以排除,6的话就麻烦了,难以查证,8的话也对比了正常的配置,没有差异,也可排除。

  现在比较有效的办法有两个:

  1、清理项目或者清理解决方案;

  2、杀进程,在任务管理器里结束与vs项目相关的host进程(不包括devenv.exe),如果有MSBuildTaskHost也要结束,然后再启动新实例,一般都能正常查看。

你可能感兴趣的:(Microsoft)