2017-07-17 3 views
1

ブレードのステータスを確認するためのレポートシステムを作成しています。私は下のコードがうまく動作していることを知っていますが、それは辛抱強く遅いです。私はPing.SendAsyncの実行に関する情報を調べたところ有望に見えましたが、ハンドラにない限りpingのステータスレポートは実行されません。その問題は、関数内の他のオブジェクトにアクセスして、Webページを正しく変更する必要があることです。ステータスメッセージ付き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枚のブレードを1つずつ実行し、数分かかります。これを並行して実行する方法やスレッドを実行する方法はありますか?私はどんな助けにも感謝します!

+0

この男はあなたがやろうとしていることをするためにPingAcyncを使いました。彼が.NETまたはまっすぐなPower Shellを使用しているかどうかはわかりませんが、Power Shellのソリューションを探して見つけました。 2つは非常に似ているので、スクリプトで探している解決策を見つけることができます。優れた機能の1つは、ISEで実行したときにステータスインジケータが表示されることです。私はISEの外でそれを試していません。 https://gallery.technet.microsoft.com/scriptcenter/Fast-asynchronous-ping-IP-d0a5cf0e/ – YetAnotherRandomUser

答えて

0

あなたが試したことを示す良いものがありませんでした。完全で正確な解決策を保証するものではありません。しかし、あなたは確かに、より古いイベントベースのモデル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がそれまでに完了していないと仮定すると)。 pingが完了すると、メソッドの実行が現在利用可能なPingReplyの有効な値で再開します。

当然、pingが完了するまで、コレクション内の各アイテムは、どのようなデフォルト状態でも起動します。これは容認できるものと思われる。そうでない場合は、pingの進行中に表示する中間状態を作成する必要があります。

+0

ワウは大変助けてくれてありがとう!それは完全に動作するように見えます。私はすべてのコードを投稿しないことをお詫びします。私はこれのためのAPIを構築しており、コードは非常に長く、これはほんの一部です。私はまた、セキュリティ上の理由からいくつかのものを含めたり変更したりしていませんでした。 "e"変数の 'pingSender.PingCompleted + =(s、e)=> tcs.SetResult(e.Reply);' にエラーが発生しました。 「このスコープで宣言することはできません。その名前は、ローカルまたはスコープを定義するためにローカルスコープを囲むために使用されるためです」 どうすれば回避できますか? – TylerIlGenio

+0

_ "すべてのコードを投稿していないことをお詫びします" _ - 心配はありません。つまり、ここではスタックオーバーフローが優先されますが、質問の不備は本当に質問を投稿する人に害を与えます。あなたはより良い質問でより良い答えを得るでしょう。たとえば、実際にコードサンプルをコンパイルできた場合は、メソッドにすでに 'e'変数があることを見落とすことはありませんでした。このコード行を 'pingSender.PingCompleted + =(s、e2)=> tcs.SetResult(e2.Reply);'に変更することでエラーを修正することができます(または、好きな2番目のラムダパラメータには一意の名前を使用します)。 –

関連する問題