我编写了一个程序,该程序扫描网络中大约10.000台计算机的正常运行时间,活动用户,空闲时间和ping。
该程序表现出色。通常在3分钟左右内检查所有计算机。
但是最近,该程序一直处于冻结状态。它已完成所有任务,但不会退出。
我像这样启动所有BackGroundWorkers:
foreach (DataRow computer in computerTable.Rows)
{
//Added check to see if computer is in inputlist for inputfilemode
if (!inputFileMode || (inputFileMode && computerList.Contains(computer["ComputerName"].ToString())))
{
BackgroundWorker bw = new BackgroundWorker();
//Determine background jobs
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.RunWorkerAsync(computer); //Start background worker
numberOfWorkers++;
}
}
int lastNr = 0;
int skipHangingJobsCounter = 0;
do
{
lastNr = numberOfWorkers;
Thread.Sleep(1000);
Console.WriteLine("Tijd: " + DateTime.Now.ToString("yyyyMMdd-HH:mm:ss") + " #Jobs queued: " + numberOfWorkers.ToString() + " Jobs/sec: " + (lastNr - numberOfWorkers).ToString() + " -ForcedShutdowns: " + forcedReboots.ToString() + " -MSIEXEC Exceptions: " + machinesMSI.ToString()); //Report progress
if (lastNr - numberOfWorkers == 0)
{
skipHangingJobsCounter++;
if (skipHangingJobsCounter > 30) break; //Safety breakout if a worker hangs
}
else
{
skipHangingJobsCounter = 0;
}
//Timing break
double minutesRunning = DateTime.Now.Subtract(startOfJob).TotalMinutes;
if (minutesRunning > 13)
{
Console.WriteLine("Job is running for 14 minutes. Job will be cancelled. Jobs queued remaining: " + numberOfWorkers.ToString());
break;
}
} while (numberOfWorkers > 0); //Wait till all jobs are finished
我想知道:这是启动和跟踪所有后台作业的最有效方法吗?创建列表数组更好吗?
我认为这会占用很多内存吗?
在do_work部分中,我有很多WMI查询,正常运行时间等。是否可能由于挂起WMI查询而导致程序无法退出?还有其他人尝试过吗?
所以基本上我有两个问题:
1-我是否以有效/正确的方式启动了后台工作人员?
2-线程中的WMI调用是否有可能导致程序无法退出?
更新:
我将代码重新编写如下。现在快了3倍。我仍然使用1个后台工作程序,但仅限于此,因此我可以对主线程提供反馈。我认为它应该工作的方式:)
主线程:
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted +=bw_RunWorkerCompleted;
bw.RunWorkerAsync();
int lastNr = numberOfWorkers;
do
{
lastNr = numberOfWorkers;
Thread.Sleep(1000); //Give feedback every second
Console.WriteLine("Tijd: " + DateTime.Now.ToString("yyyyMMdd-HH:mm:ss") + " #Jobs queued: " + numberOfWorkers.ToString() + " Jobs/sec: " + (lastNr - numberOfWorkers).ToString() + " -ForcedShutdowns: " + forcedReboots.ToString() + " -MSIEXEC Exceptions: " + machinesMSI.ToString()); //Report progress
//Timing break
double minutesRunning = DateTime.Now.Subtract(startOfJob).TotalMinutes;
if (numberOfWorkers < 3)
{
//We are waiting for 3 last workers. Give feedback which 3 thse are
foreach (Task t in taskArray)
{
if (t.Status == TaskStatus.Running)
{
Console.WriteLine("Waiting for " + taskList[t.Id]);
}
}
}
if (minutesRunning > 13)
{
Console.WriteLine("Job is running for 14 minutes. Job will be cancelled. Jobs queued remaining: " + numberOfWorkers.ToString());
break;
}
} while (!jobDone); //Wait till all jobs are finished
后台工作
static void bw_DoWork(object sender, DoWorkEventArgs e)
{
JobLauncher();
}
static void JobLauncher()
{
foreach (DataRow computer in computerTable.Rows)
{
//Added check to see if computer is in inputlist for inputfilemode
if (!inputFileMode || (inputFileMode && computerList.Contains(computer["ComputerName"].ToString())))
{
Task t = Task.Factory.StartNew(() => CheckComputer(computer));
taskList.Add(t.Id, computer["ComputerName"].ToString());
taskArray.Add(t);
numberOfWorkers++;
}
}
Task.WaitAll(taskArray.ToArray());
}
参考方案
除了所有这些,您最好使用预定义的方法来检查所有任务是否已结束。您的代码很容易出错,并且很可能会关闭整个应用程序。为什么要为每台计算机启动1个线程? 10.000个线程?对我来说似乎太过分了。
我的建议是使用任务而不是后台工作人员。如果您具有网络I / O,则很有可能await
这样做,从而提高整体性能。只需Task.WhenAll
它们,您就会注意到它们何时准备就绪。
另一种方法是使用Parrallel库。您可以Parrallel.Foreach
计算机列表,将它们拖到最多16个左右,.NET框架将为您进行所有循环和检查。
我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…
改造正在返回一个空的响应主体 - java我正在尝试使用Retrofit和Gson解析一些JSON。但是,我得到的响应机构是空的。当我尝试从对象中打印信息时,出现NullPointerException。我确保URL正确,并且我也确保POJO也正确。我正在使用jsonschema2pojo来帮助创建POJO类。这是我要解析的JSON{ "?xml": { "@versi…
每个文件合并后添加换行 - python我有很多类似以下内容的JSON文件:例如。1.json{"name": "one", "description": "testDescription...", "comment": ""} test.json{"name"…
Json到php,json_decode返回NULL - php我正在用PHP进行JSON解析器的一些API,用于存储有关遗产的信息。我在解析时遇到问题,因为它返回的是NULL值而不是数组或对象。简单的JSON代码可以很好地解析,但是可以这样:{"success":true,"totalCount":1,"data":[{"id":99694…
将ajax的值存储到javascript变量中 - javascript我有一个php文件,其中我从服务器获取数据。该php文件的输出是一个包含json格式数据的变量。PHP文件:<?php $dbHostName = "localhost"; $dbUserName = "venseld"; $dbUserPass = "wecuuu"; $dbName = &…