我正在开发一个管理网络设备的应用程序,在应用程序的某一点,我必须ping(实际上它不是ping,它是SNMP获取)所有计算机在网络中检查它的类型是否属于我的托管设备。
我的问题是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]);
}
}
}
答案 0 :(得分:0)
您的问题是您正在迭代无线程安全项List
。
如果用类似ConcurrentBag的线程安全对象替换它,你会发现线程将并行运行。
我有点困惑为什么这只是运行一个线程,我相信这是这行代码:
try
{
ihe = Dns.Resolve(host);
}
catch (Exception)
{
return;
}
我认为这会抛出异常并返回;因此你只看到一个线程。这也与您的观察结果有关,如果您添加了睡眠,它可以正常工作。
请记住,当您传递一个字符串时,您将引用传递给内存中的字符串,而不是值。无论如何,ConcurrentBag
似乎解决了您的问题。 This answer might also be relevant