【发布时间】:2014-07-01 12:06:49
【问题描述】:
我正在开发一个管理网络中设备的应用程序,在应用程序中的某个点,我必须 ping(实际上它不是 ping,它是 SNMP get)网络中的所有计算机以检查其类型是否为我的受管设备。
我的问题是 ping 网络中的所有计算机非常慢(特别是因为它们中的大多数都不会响应我的消息并且只会超时)并且必须异步完成。
我尝试使用 TLP 通过以下代码执行此操作:
public static void FindDevices(Action<IPAddress> callback)
{
//Returns a list of all host names with a net view command
List<string> hosts = FindHosts();
foreach (string host in hosts)
{
Task.Run(() =>
{
CheckDevice(host, callback);
});
}
}
但是它运行非常慢,当我暂停执行时,我检查了线程窗口,发现它只有一个线程 ping 网络,因此同步运行任务。
当我使用普通线程时,它运行得更快,但任务应该更好,我想知道为什么我的任务没有优化并行性。
**编辑** 评论要求 CheckDevice 上的代码,所以这里是:
private static void CheckDevice(string host, Action<IPAddress> callback)
{
int commlength, miblength, datatype, datalength, datastart;
string output;
SNMP conn = new SNMP();
IPHostEntry ihe;
try
{
ihe = Dns.Resolve(host);
}
catch (Exception)
{
return;
}
// Send sysLocation SNMP request
byte[] response = conn.get("get", ihe.AddressList[0], "MyDevice", "1.3.6.1.2.1.1.6.0");
if (response[0] != 0xff)
{
// If response, get the community name and MIB lengths
commlength = Convert.ToInt16(response[6]);
miblength = Convert.ToInt16(response[23 + commlength]);
// Extract the MIB data from the SNMP response
datatype = Convert.ToInt16(response[24 + commlength + miblength]);
datalength = Convert.ToInt16(response[25 + commlength + miblength]);
datastart = 26 + commlength + miblength;
output = Encoding.ASCII.GetString(response, datastart, datalength);
if (output.StartsWith("MyDevice"))
{
callback(ihe.AddressList[0]);
}
}
}
【问题讨论】:
-
这可能取决于 CheckDevice 的实际作用
-
另外,List 不是线程安全的,不应使用。 You should use a ConcurrentBag。这可能是您问题的根源。 CheckDevice 是否有任何机会锁定它?
-
到目前为止我还没有发现问题。让我们尝试一下。将 dns 检查替换为
Task.Run(() => Thread.Sleep(10000))并查看您现在是否看到许多线程正在运行。您应该假设hosts确实包含许多工作项(到底有多少?)。 -
确实,通过替换 CheckDevice(host, callback);睡觉我可以看到很多线程在睡觉
-
Liam,替换并发包的列表有效,请给出答案,我会接受它
标签: c# network-programming task-parallel-library