2017-07-17 64 views
1

我正在创建一个报告系统来检查刀片的状态。我知道下面的代码是可行的,但它很慢。我查阅了有关运行Ping.SendAsync的信息,它看起来很有希望,但它不会在ping上运行状态报告,除非它在处理程序中。问题在于,我需要访问函数中的其他对象才能正确更改网页。运行带状态消息的Ping.SendAsync

protected void RadGridDellBlade_ItemDataBound(object sender, GridItemEventArgs e) 
    { 
     if (e.Item.ItemType == GridItemType.Item || e.Item.ItemType == GridItemType.AlternatingItem) 
     { 
      thing1 t1 = new thing1(); 
      BladeRunnerDataAccess td = new BladeRunnerDataAccess(t1); 
      try 
      { 
       Image icon = (Image)e.Item.FindControl("Dell_imgIcon"); 
       BladeWorkstation blade = (BladeWorkstation)e.Item.DataItem; 
       Ping pingSender = new Ping(); 
       PingReply reply = pingSender.Send(blade.IPAddress); 

       switch (reply.Status) 
       { 
        case IPStatus.Success: 
         icon.ImageUrl = "~/Images/GreenIcon.png"; 
         break; 
        case IPStatus.TimedOut: 
         icon.ImageUrl = "~/Images/RedIcon.png"; 
         break; 
        default: 
         icon.ImageUrl = "~/Images/GrayIcon.png"; 
         break; 
       } 
       Image Dell_osbit = (Image)e.Item.FindControl("Dell_OSbit"); 
       switch (blade.BladeOSID) 
       { 
        case 1: 
         Dell_osbit.ImageUrl = "~/Images/xp.png"; 
         break; 
        case 2: 
         Dell_osbit.ImageUrl = "~/Images/32bit.png"; 
         break; 
        case 3: 
         Dell_osbit.ImageUrl = "~/Images/64bit.png"; 
         break; 
       } 
      } 
      catch (Exception ex) 
      { 

      } 
      finally 
      { 
       t1.Dispose(); 
      } 
     } 
    } 

此代码的工作原理是一次只运行一个250个刀片,需要几分钟的时间。有没有办法做到这一点平行或与线程,并保持状态检查以及?我感谢任何帮助!

+0

这个人使用PingAcync来做你想要做的事情。不知道他是使用.NET还是直接使用Power Shell,但是我偶然发现它在Power Shell中寻找解决方案。由于两者非常相似,因此您可能能够在脚本中找到您要查找的解决方案。其中一个很酷的功能是当我在ISE中运行它时有一个状态指示器。虽然我没有在ISE之外尝试过。 https://gallery.technet.microsoft.com/scriptcenter/Fast-asynchronous-ping-IP-d0a5cf0e/ – YetAnotherRandomUser

回答

0

缺乏一个很好的Minimal, Complete, and Verifiable code example显示你已经尝试过,我不能保证一个完整和准确的解决方案。但是,您当然可以将旧的基于事件的模型Ping.SendAsync()async/await合并,并将您的代码转换为相当好的异步实现。

我从你的方法的名称中收集你正在做这项工作,因为每个项目都绑定到一个容器控件。所以你没有向我们展示250个项目的实际循环。我假设它足以以异步方式运行事件处理程序的每个调用。为此:

protected async void RadGridDellBlade_ItemDataBound(object sender, GridItemEventArgs e) 
{ 
    if (e.Item.ItemType == GridItemType.Item || e.Item.ItemType == GridItemType.AlternatingItem) 
    { 
     thing1 t1 = new thing1(); 
     BladeRunnerDataAccess td = new BladeRunnerDataAccess(t1); 
     try 
     { 
      Image icon = (Image)e.Item.FindControl("Dell_imgIcon"); 
      BladeWorkstation blade = (BladeWorkstation)e.Item.DataItem; 
      Ping pingSender = new Ping(); 
      TaskCompletionSource<PingReply> tcs = new TaskCompletionSource<PingReply>(); 

      pingSender.PingCompleted += (s, e2) => tcs.SetResult(e2.Reply); 
      pingSender.SendAsync(blade.IPAddress, null); 
      PingReply reply = await tcs.Task; 

      switch (reply.Status) 
      { 
       case IPStatus.Success: 
        icon.ImageUrl = "~/Images/GreenIcon.png"; 
        break; 
       case IPStatus.TimedOut: 
        icon.ImageUrl = "~/Images/RedIcon.png"; 
        break; 
       default: 
        icon.ImageUrl = "~/Images/GrayIcon.png"; 
        break; 
      } 
      Image Dell_osbit = (Image)e.Item.FindControl("Dell_OSbit"); 
      switch (blade.BladeOSID) 
      { 
       case 1: 
        Dell_osbit.ImageUrl = "~/Images/xp.png"; 
        break; 
       case 2: 
        Dell_osbit.ImageUrl = "~/Images/32bit.png"; 
        break; 
       case 3: 
        Dell_osbit.ImageUrl = "~/Images/64bit.png"; 
        break; 
      } 
     } 
     catch (Exception ex) 
     { 

     } 
     finally 
     { 
      t1.Dispose(); 
     } 
    } 
} 

至于引发事件,并呼吁上述处理程序,处理程序将尽快到达await tcs.Task;语句完成工作目标(假设平已经不是那么完成)。一旦ping完成,该方法的执行将继续,现在可用PingReply的有效值。

当然,在ping完成之前,集合中的每个项目都会有任何默认启动的状态。大概这是可以接受的。如果没有,您必须创建一些中间状态才能在ping过程中显示。

+0

非常感谢你的帮助!它看起来会很完美。我很抱歉没有发布所有的代码。我为此构建了一个API,代码很长,而这只是它的一小部分。出于安全原因,我也没有包含/改变某些内容。 我在'pingSender.PingCompleted + =(s,e)=> tcs.SetResult(e.Reply);' '为'e'变量时出错。它说:“不能在这个范围内声明,因为这个名字被用在一个封闭的本地范围中来定义一个本地或参数”我怎样才能解决它? – TylerIlGenio

+0

_“我很抱歉没有发布所有代码”_ - 没有问题。我的意思是,我们更喜欢Stack Overflow,但是问题的缺陷只会影响发布问题的人。你会得到更好的答案和更好的问题。例如,你得到的错误信息,如果我能够真正编译你的代码示例,我不会忽略该方法已经有一个'e'变量。您可以通过将该行代码更改为'pingSender.PingCompleted + =(s,e2)=> tcs.SetResult(e2.Reply);'(或者使用您喜欢的第二个lambda参数的任何唯一名称来修复错误。 –