获取错误:
未处理的类型异常 'System.StackOverflowException' 发生在System.Management.dll
中
我的书帖:
[管理原生过渡]
System.Management.dll!System.Management.ManagementScope.InitializeGuts(对象 o)+ 0x1a3字节
System.Management.dll!System.Management.ManagementScope.Initialize() + 0xa3字节
System.Management.dll!System.Management.ManagementScope.Connect() + 0x5 bytes
Computer_Managerment.exe!Computer_Managerment.WMI.ComputerInformation.ComputerInformation(string ComputerName =“pc357”,字符串 UserName =“”,string Password =“”) 第228行+ 0xd字节C#
Computer_Managerment.exe!Computer_Managerment.ScanAllComputers.Workerthread() 第95行+ 0x1e字节C#
mscorlib.dll中!System.Threading.ThreadHelper.ThreadStart_Context(对象 状态)+ 0x66字节
mscorlib.dll中!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext 执行上下文, System.Threading.ContextCallback 回调,对象状态)+ 0x6f 字节
mscorlib.dll中!System.Threading.ThreadHelper.ThreadStart() + 0x44字节
我得到stackoverflow的代码:
try
{
gManager = new ManagementScope(ConnectStr, oConn); //\\\\" +
gManager.Connect(); // This is where the crash happens
}
catch (UnauthorizedAccessException)
{
// Code removed
}
该代码基本上适用于此诉讼
1)我有一份AD(超过1k)的所有计算机列表
2)我有10个线程旋转一个while循环,从Que List中获取一个compuer
3)当他们有一个计算机名时,他们会创建一个执行gManager.Connect()的ComputerInformation类的实例;再次崩溃
我的理解是这个崩溃/堆栈溢出发生在本机代码中,但我认为我做错了。如果需要更多代码,请发布它。
Pr请求更多代码:这是工作人员居住的代码(Normaly约10名工作人员)
internal struct stWorkList
{
public Queue<string> Work;
public List<ComputerInformation> CompInfo;
public int FailedComputers;
public int FailedPingCheck;
public int SuccessComputers;
public int TotalComputers;
public int FailedAuth;
public int FailedToContactWMIServer;
}
stWorkList gWorkList;
void Workerthread()
{
Monitor.Enter(gUserName);
Monitor.Enter(gPassword);
string UserName = gUserName;
string Password = gPassword;
Monitor.Exit(gPassword);
Monitor.Exit(gUserName);
while (true)
{
Monitor.Enter(gWorkList.Work);
if (gWorkList.Work.Count == 0)
{
Monitor.Exit(gWorkList.Work);
break;
}
string ComputerName = gWorkList.Work.Dequeue();
Monitor.Exit(gWorkList.Work);
if (ComputerName == null)
continue;
ComputerInformation iCI = new ComputerInformation(ComputerName, UserName, Password);
Monitor.Enter(gWorkList.CompInfo);
gWorkList.CompInfo.Add(iCI);
switch (iCI.Status)
{
case eComputerCheckStatus.Connected:
gWorkList.SuccessComputers++;
break;
case eComputerCheckStatus.FailedPingTest:
gWorkList.FailedPingCheck++;
gWorkList.FailedComputers++;
break;
case eComputerCheckStatus.UnauthorizedAccessException:
gWorkList.FailedComputers++;
gWorkList.FailedAuth++;
break;
case eComputerCheckStatus.FailedToContactWMIService:
gWorkList.FailedToContactWMIServer++;
gWorkList.FailedComputers++;
break;
case eComputerCheckStatus.UnkownFailed:
gWorkList.FailedComputers++;
break;
}
Monitor.Exit(gWorkList.CompInfo);
iCI.Dispose();
}
}
ComputerInformation类中的构造函数
public ComputerInformation(string ComputerName, string UserName, string Password)
{
gComputerName = ComputerName;
gHardDriveList = new List<stHarddiskInfo>();
gProccessInfo = new List<stProccessInfo>();
gCPUInfo = new List<stCPUInformation>();
gOSInfo = new stOSInfo();
gMemoryInfo = new List<stMemoryInfo>();
gPreformanceMemory = new stPreformanceMemory();
gProccessOverView = new stProccessOverview();
gMonitorInfo = new List<stMonitorInfo>();
gNetworkInfo = new List<stNetworkInfo>();
netMon = new Ping();
PingResponse response = netMon.PingHost(ComputerName, 1);
if (response == null || response.PacketsReceived == 0)
{
gStatus = eComputerCheckStatus.FailedPingTest;
gHasError = true;
return;
}
gComputerIP = response.ServerEndPoint.Address.ToString();
ConnectionOptions oConn = new ConnectionOptions();
oConn.Timeout = new TimeSpan(0, 0, 10);
if (!string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(UserName))
{
oConn.Username = UserName;
oConn.Password = Password;
}
string ConnectStr = "\\\\" + ComputerName + "\\root\\cimv2";
try
{
gManager = new ManagementScope(ConnectStr, oConn); //\\\\" +
gManager.Connect(); // this is where it crashes
}
catch (UnauthorizedAccessException)
{
gStatus = eComputerCheckStatus.UnauthorizedAccessException;
gHasError = true;
return;
}
catch (Exception Ex)
{
if (Ex.Message.Contains("The RPC server is unavailable"))
{
gStatus = eComputerCheckStatus.FailedToContactWMIService;
}
else
gStatus = eComputerCheckStatus.UnkownFailed;
gHasError = true;
return;
}
gStatus = eComputerCheckStatus.Connected;
try
{
GetRunningProccessInfo();
GetCPUInformation();
GetHardDriveInfo();
GetOSInfo();
GetMemoryInfo();
GetMonitorInfo();
GetComputerSystem();
}
catch
{
gStatus = eComputerCheckStatus.UnkownFailed;
gHasError = true;
}
}
答案 0 :(得分:1)
这纯粹是猜测,但如果你做错了,那么它应该在传递给gManger初始化的参数中。
接下来,如果您要发布内容,则是oConn对象实例化。可能会有一些不正确的参数导致以后出现问题。
我没有在我的编码中使用这个类,所以除了查看参数外,这一切都是......有一点需要注意:
关于ManagementScope的MSDN文章有一个关于这个库无法被部分受信任的代码使用的有趣的tid-bit。
有关详细信息,请参阅this页面的.Net Framework安全性部分。
否则,祝你好运。
编辑:只是另外一个想法。由于这发生在多个线程中,如果尝试从线程中读取/写入字符串,则可能会出现一些问题。从代码中查看更大的上下文可能会有所帮助。
对不起,我在这里没有更多的帮助,但也许我的想法会帮助你(或其他任何人)解决这个问题。
答案 1 :(得分:1)
我怀疑你会在这里得到一个吸烟枪答案,因为你没有发布足够的代码。大多数StackOverflow错误都来自循环错误。
我运行您发布的代码没有任何问题。以下是我将如何调试:
确保您没有在线程上共享任何对象!关闭所有连接,不要重复使用它们。
尝试以上操作,如果您仍然遇到问题,请发布更多代码。
答案 2 :(得分:1)
好点开始,就是检查这段代码是否抛出异常。
ManagementScope scope = new ManagementScope(@"\\localhost\root\cimv2");
scope.Connect();
<强>更新强>
您在iCI初始化时没有Monitor.Enter / Exit块(以及现有问题异常)
检查这是否是您可以进行简单记录的问题。
gManager = new ManagementScope(ConnectStr, oConn);
Debug.WriteLine("connect to "+ComputerName+" by "+UserName+"/"+Password);
gManager.Connect(); // this is where it crashes
Debug.WriteLine("success on "+ComputerName+" by "+UserName+"/"+Password);
如果我的建议是正确的,你会在日志中收到这样的信息:
“连接到计算机1”
“连接到计算机2”
并且不可避免地例外。