VS 2008 调试:System.ArgumentException?
问题: 我有一个表单项目,它实例化一个在单独的 dll 项目中定义的类。当运行使用此 dll 的表单应用程序时,一切都运行得很好,但是,当我设置断点来检查 dll 项目中定义的类型的对象时,我的监视窗口中出现错误。
需要了解的一些事项可能很重要:
- dll 项目使用不安全和非托管代码。
- 此问题发生在调用任何不安全函数之前。
- 启用非托管代码调试。
- 我知道 dll 的符号已加载。
- 我知道调试器加载的 dll 版本与应用程序使用的版本相同。
- 我已经清理并删除了输出目录然后重建。
- 他们使用相同的.NET 版本。
示例:如果我将其添加到我的监视窗口 MyDllType.SomeProperty
我会看到此内容(仅在监视窗口中):
'MyDllType.SomeProperty' throws类型为“System.ArgumentException”的异常消息:“找不到对象实例上的方法。”
但是,如果我要添加 Debug.Writeline(MyDllType.SomeProperty );
在同一时刻,我不会遇到任何异常,并且它将正确显示在输出控制台中。
此外:如果我要创建 dll 项目中定义的结构类型列表并将其添加到我的监视窗口中,我会看到以下内容(仅在监视窗口中):
// My Dll Project
public struct MyDllStruct
{
public int x;
public int y;
public int z;
}
// Snippet from a function block in forms project
List<MyDllStruct> structList = new List<MyDllStruct>();
// Add a bunch of stuff to the list
// <-- Insert a breakpoint here
}
当我中断并添加 < code>structList 到监视窗口我得到:
无法计算表达式。不支持操作。未知错误:0x8004f0ed。
但是,我再次在同一点添加Debug.Writeline(structList.Count);
,然后我就不会得到任何结果异常,并且计数将正确显示在输出控制台中。
完整示例:
// My Dll Project
public class MyDllType
{
public MyDLLType()
{
this.someProperty = 123456;
}
private int someProperty;
public int SomeProperty
{
get{ return this.someProperty; }
set{ this.someProperty = value; }
}
}
public struct MyDllStruct
{
public int x;
public int y;
public int z;
}
// My Forms Project
public class SomeController
{
public SomeController()
{
this.dllType = new DllType();
List<MyDllStruct> structList = new List<MyDllStruct>();
// <-- For example, I get both aformentioned problems if i break here (or anywhere else these objects have been instantiated)
}
private MyDllType dllType;
}
正如您可能想象的那样,这使得调试我的应用程序变得非常困难:) 任何帮助将不胜感激。
The Problem:
I have a forms project which instantiates a class that is defined in a separate dll project. When running the forms application which uses this dll everything runs perfectly fine, however, when I set a breakpoint to inspect objects of types that are defined in the dll project I get errors in my watch window.
Some things that may be important to know:
- The dll project uses unsafe and unmanaged code.
- This problem occurs before any unsafe functions are called.
- Unmanaged code debugging is enabled.
- I know the symbols are loaded for the dll.
- I know the version of the dll loaded by the debugger is the same used by the application.
- I have cleaned and deleted the output directory then rebuilt.
- They are using the same .NET version.
Example: if I were to add this to my watch window MyDllType.SomeProperty
I would see this (in the watch window only):
'MyDllType.SomeProperty' threw an exception of type 'System.ArgumentException' Message: "Cannot find the method on the object instance."
However, if I were to add Debug.Writeline(MyDllType.SomeProperty);
at that same exact point then I would get no exception and it would be correctly displayed in the output console.
Furthermore: if I were to create a list of a struct type defined in the dll project and add it to my watch window I would see this (in the watch window only):
// My Dll Project
public struct MyDllStruct
{
public int x;
public int y;
public int z;
}
// Snippet from a function block in forms project
List<MyDllStruct> structList = new List<MyDllStruct>();
// Add a bunch of stuff to the list
// <-- Insert a breakpoint here
}
When i break and add structList
to the watch window I get:
Unable to evaluate the expression. Operation not supported. Unknown error: 0x8004f0ed.
However, once again I were to add Debug.Writeline(structList.Count);
at that same exact point then I would get no exception and it the count would be correctly displayed in the output console.
Full Example:
// My Dll Project
public class MyDllType
{
public MyDLLType()
{
this.someProperty = 123456;
}
private int someProperty;
public int SomeProperty
{
get{ return this.someProperty; }
set{ this.someProperty = value; }
}
}
public struct MyDllStruct
{
public int x;
public int y;
public int z;
}
// My Forms Project
public class SomeController
{
public SomeController()
{
this.dllType = new DllType();
List<MyDllStruct> structList = new List<MyDllStruct>();
// <-- For example, I get both aformentioned problems if i break here (or anywhere else these objects have been instantiated)
}
private MyDllType dllType;
}
As you could probably imagine, this is making it really hard to debug my application :) Any help would be much appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这并不是一个答案,而是对“观察窗口”与“调试打印输出”之谜的一些见解。
Visual Studio 中的“监视”窗口使用内置的托管表达式计算器来评估您的输入,例如
structList
。因此,作为运行时解析器,它与编译器本身完全不同,并且只能理解表达式的子集。您可以在此处阅读其详细说明。因此,这个表达式求值器有可能无法正确处理来自不安全 DLL 的类型,而且我似乎隐约记得自己也经历过这种情况。作为一个“轻量级编译器”,它确实有一些缺点,这可能是其中之一。
另一方面,
Debug.WriteLine()
工作正常,因为传递给它的表达式是由 C# 编译器本身在编译时处理的。This is not an answer as such, but some insight into the Watch-window vs Debug-printout mystery.
The Watch window in Visual Studio evaluates your input, say
structList
, using a built-in managed expression evaluator. As a runtime parser it is therefore a completely different beast than the compiler itself and only understands a subset of expressions. You can read a fine description of it here.Therefore it's possible - and I seem to vaguely remember having experienced this myself - that this expression evaluator cannot properly handle types from an unsafe DLL. As a "lightweight compiler" it certainly does have some shortcomings, and this is possibly one of them.
On the other hand,
Debug.WriteLine()
works fine because the expression passed to it is processed at compile-time by the C# compiler itself.您可以检查您的配置管理器并确认所有项目都编译为“任何 CPU”吗?可能性不大,但我知道有人遇到了类似的问题,而且我隐约记得他的项目被设置为 x86 和任何 CPU 的混合。
Can you check your configuration manager and confirm that all projects compile to 'Any CPU'? Long shot, but I know someone who had a similar problem, and I vaguely to remember he had projects that were set to a mix of x86 and Any CPU.