每当用户报告错误时,例如
System.Runtime.InteropServices.SEHException - 外部组件引发了异常?
我作为程序员可以做些什么来确定原因?
场景:一个用户(使用我公司编写的程序)报告了此错误.这可能是也可能不是一次性错误.他们提到,在上个月,计算机已经两次"停止工作".我从经验中学到了,不是太过于字面意思,因为它通常意味着与计算机有关的人没有按预期工作.他们无法给我更多细节,我找不到任何记录错误.因此它可能是也可能不是这个错误.
从堆栈跟踪中,实际错误是在构造一个不直接调用任何互操作代码的类时,但可能因为该对象可能是与DevExpress Grid数据绑定的列表的一部分而复杂化.
错误被未处理的异常例程"捕获",该例程通常会关闭程序,但可以选择忽略并继续.如果他们选择忽略错误,则程序继续工作,但下次运行此例程时会再次出现错误.但是,在关闭并重新启动应用程序后,它不会再次出现.
有问题的电脑似乎没有压力.它正在运行Vista Business,拥有2GB的内存,根据任务管理器,我们的应用程序只使用了大约一半,只有大约200Mb.
还有一条信息可能相关或不相关.同一程序的另一部分使用第三方组件,它实际上是一个围绕本机dll的dotnet包装器,这个组件确实有一个已知的问题,偶尔,你得到一个
尝试读取或写入受保护的内存.这通常表明其他内存已损坏
组件制造商表示,这已在我们内部使用的最新版本的组件中修复,但尚未向客户提供.
鉴于错误的后果很少(没有工作丢失并重新启动程序并返回到最多只需要一分钟的时间)并且考虑到客户将很快获得新版本(更新后的第三个 - 派对组件),我显然可以交叉手指,希望错误不再发生.
但还有什么我可以做的吗?
我试图找到两个通用列表之间的区别,如下例所示.即使t1和t2包含相同的属性,它们也不是同一个对象,所以我需要实现IEqualityComparer.
这似乎与这个例子有关,但真正的类有几个其他属性,我也需要对其他一些类做同样的事情.
所以我想知道我是否正在重新发明轮子?
是否有更简单的方法来比较两个对象的所有属性?目前,我真的只需要处理包含简单类型的类,但是我会有一个比较器,它可以处理包含其他类实例的类.
void Main()
{
var t1 = new Sizes { Name = "Test" , Size = 1} ;
var t2 = new Sizes { Name = "Test" , Size = 1} ;
var list1 = new List<Sizes>();
var list2 = new List<Sizes>();
list1.Add(t1);
list2.Add(t2);
var differences = list2.Except(list1 , new SizesComparer());
// differences should be empty.
}
public class Sizes
{
public string Name { get; set; }
public int Size { get; set; }
}
public …Run Code Online (Sandbox Code Playgroud) 我们的一些非技术用户遇到问题,我们的应用程序中的对话框有时可能会显示在主窗体后面,并且应用程序不接受任何输入,直到消息框(他们看不到)被取消.
应用程序是用C#编写的,消息框是标准的,例如代码可以像MessageBox.Show(消息,标题)一样简单,消息框可以由主UI线程创建(即不是某些后台线程).应用程序不必全屏运行,但我们90%的用户都是全屏运行它.
大多数时候((可能> 99%)消息框显示正确,我从来没有设法看到它出错了,但我看到一台机器出错了.
我注意到的一件事是,如果你有一个显示对话框的应用程序,那么当你查看你的任务管理器时,你只能在应用程序列表中看到一个条目.每当隐藏消息框时,您将看到两个条目,一个用于主应用程序,另一个用于此消息框.
一旦你知道发生了什么事情就很容易解决问题,但是我们的一些非技术用户对此感到困惑并最终关闭了他们的计算机.(而那些使用远程桌面的人在解决问题时更加困惑).
我不认为它与操作系统有关,因为我已经看到它发生在Vista中并且被告知它也发生在Windows 2003服务器上的终端会话中.
有什么事情知道为什么会发生这种情况,更重要的是,如果可以做任何事情来避免它吗?
我在使用反射转储一些对象属性的例程上得到此错误,类似于下面的代码.
MemberInfo[] members = obj.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance) ;
foreach (MemberInfo m in members)
{
PropertyInfo p = m as PropertyInfo;
if (p != null)
{
object po = p.GetValue(obj, null);
...
}
}
Run Code Online (Sandbox Code Playgroud)
实际错误是"调用目标抛出了异常",内部异常为"只能在Type.IsGenericParameter为true的Type上调用Method".
在调试器obj的这个阶段出现
{Name = "SqlConnection" FullName = "System.Data.SqlClient.SqlConnection"}
Run Code Online (Sandbox Code Playgroud)
使用System.RuntimeType类型
方法m是{System.Reflection.MethodBase DeclaringMethod}
请注意,obj的类型为System.RuntimeType,成员包含188个项目,而简单的typeof(System.Data.SqlClient.SqlConnection).GetMembers(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)仅返回65.
我尝试在obj和p.PropertyType上检查isGenericParameter,但对于大多数属性(包括p.GetValue工作的那些属性),这似乎都是错误的.
那么究竟什么是"Type.IsGenericParameter为真的类型",更重要的是如何在没有try/catch的情况下避免这个错误?
据我所知,将方法标记为不安全将禁用对该代码的一些CLR检查,但除了DLL/EXE无法运行之外,这对系统的其他部分是否安全有任何影响.不受信任的环境.
特别是,
我有详重绘在64位Windows嵌套的控制问题,在这里和一个解决方案(即似乎工作的一个)涉及不安全的代码,我想明白,添加此代码有我的项目的效果.
有没有专门监视/检测参数嗅探问题的工具,而不是报告需要很长时间的查询的工具?
我刚刚遇到参数嗅探问题.(它不是太严重,因为它导致报告需要大约2分钟才能运行而不是几秒钟如果正确缓存,如果重新编译可能需要30秒.而且因为报告通常每月只运行几次,所以不是真正的问题).
但是,既然我写了报告并且我知道它做了什么,我很好奇并且正在调查和使用SQL事件探查器,我可以在查询计划中看到估计行数为1的部分,但实际行数是几十万.
所以,让我感到震惊的是,如果SQL有这些数字(或者至少可以得到这些数字),那么也许有一些方法可以让sql跟踪并报告哪些计划显着.
假设我有一个类TestCollection,用于保存Test类型的对象并定义为
public class TestCollection : CollectionBase
Run Code Online (Sandbox Code Playgroud)
这允许我以集合方式遍历集合
foreach(object o in collection)
...
Run Code Online (Sandbox Code Playgroud)
要么
foreach(Test t in collection)
Run Code Online (Sandbox Code Playgroud)
但是不允许我使用新的Linq查询.
如果我将类的定义更改为
public class TestCollection : CollectionBase, IEnumerable<Test>
Run Code Online (Sandbox Code Playgroud)
并添加一个方法
public new IEnumerator<Test> GetEnumerator()
{
foreach (Test o in this.List)
yield return o ;
}
Run Code Online (Sandbox Code Playgroud)
然后linq查询可用.
但是,这个新方法不仅仅调用linq查询,而且还在遗留代码中调用(即在foreach(集合中的对象o)和foreach(集合中的Test)期间).
迭代通过集合的旧方法和假设集合中的所有项目都是Test类型的新方法之间有什么区别吗?我知道添加IEnumerator方法会导致程序抛出异常,如果它找到除Test之外的任何类型,但想知道我是否忽略了任何东西.
每当我调试我的程序时,我有时会遇到几个错误,要求我将磁盘插入驱动器E和驱动器F.这似乎与VS有关,寻找最初在这些驱动器上开发的第三方组件的来源,例

如果我一直按取消,那么我的调试会话继续,但它很烦人.我该如何阻止这种情况发生?
注意,我不是要尝试调试这些库,而是在" 选项/调试"下勾选" 启用我的代码 ".
假设我有一个表示订单行的类,例如
public class Line
{
public string Code ;
public string No ; // Invoice Number
public DateTime Date ;
public string Product ;
public decimal Quantity ;
}
Run Code Online (Sandbox Code Playgroud)
和一系列行,例如
List<Line> myList = new List<Line>();
myList.Add(new Line() { Code = "ABC001", No = "1001" ,Date = new DateTime(2012,4,1) , Product = "X", Quantity= 1m});
myList.Add(new Line() { Code = "ABC001", No = "1001" ,Date = new DateTime(2012,4,1) , Product = "Y", Quantity= 1m});
myList.Add(new Line() { Code = "ABC002", No …Run Code Online (Sandbox Code Playgroud) 假设我有两个列表,如何遍历每个子列表的每个可能组合,这样每个项目只出现一次.
我想一个例子可能是你有员工和工作,你想把他们分成团队,每个员工只能在一个团队中,每个工作只能在一个团队中.例如
List<string> employees = new List<string>() { "Adam", "Bob"} ;
List<string> jobs = new List<string>() { "1", "2", "3"};
Run Code Online (Sandbox Code Playgroud)
我想要
Adam : 1
Bob : 2 , 3
Adam : 1 , 2
Bob : 3
Adam : 1 , 3
Bob : 2
Adam : 2
Bob : 1 , 3
Adam : 2 , 3
Bob : 1
Adam : 3
Bob : 1 , 2
Adam, Bob : 1, 2, 3
Run Code Online (Sandbox Code Playgroud)
我尝试使用这个 stackoverflow问题的答案来生成每个可能的员工组合和每个可能的工作组合的列表,然后从每个列表中选择一个项目,但这就是我得到的.
我不知道列表的最大大小,但肯定会小于100,可能还有其他限制因素(例如每个团队的员工人数不超过5人)
更新 …
c# ×9
winforms ×2
.net ×1
.net-2.0 ×1
algorithm ×1
collections ×1
generics ×1
linq ×1
messagebox ×1
monitoring ×1
performance ×1
reflection ×1
sql-server ×1
unsafe ×1