2017-07-17 67 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參數的任何唯一名稱來修復錯誤。 –