C#多线程ping

C#多线程ping,c#,multithreading,ping,C#,Multithreading,Ping,我正在开发一个网络监控应用程序,它可以ping(未知)数量的主机。到目前为止,我有下面的代码。我用函数zping创建了一个类PingHost,并在计时器的帮助下每2秒调用一次,让这两个ping完成,即使其中一个得到TimedOut。但我认为更好的解决方案是为每个ping生成一个新线程,这样每个主机的ping都是独立的 谁能告诉我怎么做 namespace pinguin { public partial class Form1 : Form { public Fo

我正在开发一个网络监控应用程序,它可以ping(未知)数量的主机。到目前为止,我有下面的代码。我用函数
zping
创建了一个类
PingHost
,并在计时器的帮助下每2秒调用一次,让这两个ping完成,即使其中一个得到
TimedOut
。但我认为更好的解决方案是为每个ping生成一个新线程,这样每个主机的ping都是独立的

谁能告诉我怎么做

namespace pinguin
{
    public partial class Form1 : Form
    {
        public Form1()
        {

            InitializeComponent();


        }

        private void timer1_Tick(object sender, EventArgs e)
        {

            PingHost caca = new PingHost();
            PingHost caca1 = new PingHost();
            this.label1.Text = caca.zping("89.115.14.160");
            this.label2.Text = caca1.zping("89.115.14.129");



        }

    }

    public class PingHost
    {


        public string zping(string dest)
        {
            Application.DoEvents();
            Ping sender = new Ping();
            PingOptions options = new PingOptions();
            options.DontFragment = true;

            string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            int timeout = 50;
            int failed = 0;
            int pingAmount = 5;
            string stat = "";
            PingReply reply = sender.Send(dest, timeout, buffer, options);
            if (reply.Status == IPStatus.Success)
            {
                stat = "ok";
            }
            else
            {
                stat = "not ok!";
            }



            return stat;
        }
    }
}

如果使用.NET 4,则可以使用。

如果使用.NET 4,则可以使用。

您可以处理
Ping.PingCompleted
事件:

ping.PingCompleted += new PingCompletedEventHandler(ping_PingCompleted);
然后使用:

ping.SendAsync()

旁注:为您的类和例程选择更合适的名称。PingHost更适合作为例程名称

您可以处理
Ping。PingCompleted
事件:

ping.PingCompleted += new PingCompletedEventHandler(ping_PingCompleted);
然后使用:

ping.SendAsync()

旁注:为您的类和例程选择更合适的名称。PingHost更适合作为例程名称

一旦我编写了这样一个解决方案(它不断地ping大约300台机器):

公共类ManyAdressPing{
私人只读bool bAutoStarted;
private readonly CancellationTokenSource cancel=新的CancellationTokenSource();
公共ConcurrentDictionary pingi=新ConcurrentDictionary();
公共ManyAdressPing(bool AutoStarted=true){
bAutoStarted=自动启动;
}
public int CountPings=>pingi.Count;
public void AddPingAddress(IPAddress addr,int-msTimeOut=3000,int-BetweenPing=3000){
var oap=新的OneAddressPing(addr、cancel.Token、msTimeOut、BetweenPing);
如果(bAutoStarted)oap.Start();
pingi.TryAdd(oap.ipAddress,oap);
}
公共无效删除地址(IPAddress addr){
if(pingi.TryRemove(addr,out var p))p.Stop();
}
公共停车场(){
取消;
foreach(pingi中的var对)pair.Value.Stop();
}
公共PingReply GetReply(IPAddress addr){
if(pingi.ContainsKey(addr))返回pingi[addr].GetReply();
返回null;
}
公共元组GetSuccessOperation(IPAddress addr){
if(pingi.ContainsKey(addr))返回pingi[addr].GetSuccessOperation();
返回null;
}
public PingReply[]GetReply(){
PingReply[]ret=pingi.Values.Select(x=>x.GetReply()).ToArray();
返回ret;
}
public PingInfo GetPingInfo(IPAddress addr){
if(pingi.ContainsKey(地址)){
var ret=new PingInfo();
var p=pingi[addr];
ret.reply=p.GetReply();
ret.SuccessPing=p._SuccessReply;
ret.FailPing=p.\u FailReply;
ret.lastsuccesping=p.lastsuccesfullping;
返回ret;
}
返回null;
}
公共bool IsPinged(IPAddress addr){
if(pingi.ContainsKey(addr))返回true;
返回false;
}
公共IP地址[]GetAddressesPing(){
返回pingi.Keys.ToArray();
}
}
公共类PingInfo{
公开答辩;
公共长成功=0;
公共长故障=0;
公共日期时间上次成功;
公共重写字符串ToString(){
返回$“Sping:{SuccessPing}last={lastsucessping},Fping:{FailPing},reply:{reply}”;
}
}
公共类一寻址{
公共静态字节[]bu={
0
};
公众长时间回复;
公众长期成功回复;
私有boolbstop=false;
私有只读取消令牌取消令牌;
public DateTime lastsuccesfullping=DateTime.MinValue;
公共int mSecBetweenPing=3000;
公众平平,;
公共电话;
私有任务pTask;
//这是一个自行编写的后进先出堆栈
公共LightQueue replys=新的LightQueue(10);
私有只读自动重置事件=新自动重置事件(假);
私有记录器日志=空;
私有任务ping=null;
公共OneAddressPing(IPAddress addr,CancellationToken ct,int timeOut=3000,int BetweenPing=3000,Logger\u log=null){
ipAddress=addr;
popt=新的PingOptions();
popt.DontFragment=false;
取消令牌=ct;
mSecTimeOut=超时;
mSecBetweenPing=BetweenPing;
log=_log;
}
public int mSecTimeOut{get;set;}=3000;
公共IPAddress IPAddress{get;set;}
public int CountPings=>replys.Length;
私有void SetReply(PingReply rep){
如果(rep==null)返回;
答复.付诸表决(代表);
if(rep.Status==IPStatus.Success){
联锁。增量(参考成功回复);
LastSuccessfullPing=DateTime.Now;
}否则{
联锁增量(参考失效回复);
}
}
公共异步任务启动(){
if(pTask==null | | pTask.Status!=TaskStatus.Running){
ping=新ping();
Task.Factory.StartNew(PingCircle,TaskCreationOptions.RunContinuationsAsynchronous | TaskCreationOptions.LongRunning);pTask=Task.Run(PingCircle,cancellationToken);
}
}
公共停车场(){
if(pTask.Status==TaskStatus.Running){
bStop=true;
试一试{
pTask.Wait(mSecTimeOut,cancellationToken);
}捕获(例外情况除外){
ErrorSource($“错误ping停止:{ex.Message}”);
} 
}
}
专用异步任务PingCircle(){
while(cancellationToken.IsCancellationRequested==false&&!bStop){
试一试{
试一试{
PingReply rep=等待ping.SendPingAsync(ipAddress、mSecTimeOut、bu、popt);
如果(rep!=null)SetReply(rep);
}捕获(pingp异常){
//忽略ping错误
Debug.WriteLine($“error:{p}”);
}捕获(异常ee){
日志?.ErrorSource(ee);
Debug.WriteLine($“error:{ee}”);