小弟想將SQL所存好的IP去分別Ping一次,
那麼沒ping通的設備就排序在ListView的最上層,
但好像都沒辦法這樣排序。
小弟已經有事先與ChatGPT所提供的資訊參考方向去修改
但後續ChatGPT也說code沒問題(當然我知道這方式是參考用)
所以想詢問大大有無這方面的解決方式。
c#
namespace TestWeb1
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ListView1.DataSource = GetData();
ListView1.DataBind();
}
}
protected async void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
try
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
System.Data.DataRowView DRV = (System.Data.DataRowView)e.Item.DataItem;
var pingitems = (string)DRV.Row.ItemArray[0];
//參考官方Ping方式
Ping ping = new Ping();
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
PingOptions options = new PingOptions(64, true);
// Wait 1 seconds for a reply.
int timeout = 1000;
PingReply pingReply = await ping.SendPingAsync(pingitems, timeout, buffer, options);
var lab = e.Item.FindControl("color") as HtmlControl;//找到html定義顏色群組
if (pingReply.Status != IPStatus.Success)
{
lab.Attributes.Add("class", "red");
}
else
{
SortDirection direction = SortDirection.Ascending;
pingitems = direction == SortDirection.Ascending ? pingitems : "";
lab.Attributes.Add("class", "mediumseagreen");
}
}
}
catch (Exception ex)
{
Response.Write("<script language='javascript'>alert(\"" + "錯誤訊息 : " + ex.Message.Replace("\r\n", "") + "\");</script>");
}
}
protected void Timer1_Tick(object sender, EventArgs e)
{
Lable1.Text = "主機時間:" +DateTime.Now.ToString();
}
protected void ListView1_Sorting(object sender, ListViewSortEventArgs e)
{
// Get the sort expression and sort direction from the event args
string sortExpression = e.SortExpression;
SortDirection sortDirection = e.SortDirection;
DataTable data = GetData();
data.DefaultView.Sort = sortExpression + " " + (sortDirection == SortDirection.Ascending ? "ASC" : "DESC");
ListView1.DataSource = data;
ListView1.DataBind();
}
private DataTable GetData()
{
DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection("Data Source=LAPTOP-8RO7LF5C;Initial Catalog=edtweb;Integrated Security=True"))
{
using (SqlCommand cmd = new SqlCommand("SELECT ip,name FROM edtdata", con))
{
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
//排序
dt.DefaultView.Sort = "ip DESC";
dt = dt.DefaultView.ToTable();
}
}
return dt;
}
}
}
aspx
<%@ Page Async="true" Title="" Language="C#" MasterPageFile="~/MasterPage.Master" AutoEventWireup="true" CodeBehind="MonitorStatus.aspx.cs" Inherits="TestWeb1.WebForm1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<!-- 設定時間更新1秒 -->
<asp:Timer id="Timer1" runat="server" Interval="1000" OnTick="Timer1_Tick" />
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:Label ID="Lable1" runat="server" />
<asp:ListView ID="ListView1" runat="server" GroupItemCount="3" OnSorting="ListView1_Sorting" OnItemDataBound="ListView1_ItemDataBound">
<AlternatingItemTemplate>
<td runat="server" style="" id="color">
<style type="text/css">
.red {
background-color: red;
}
.mediumseagreen {
background-color: mediumseagreen;
}
</style>
name:
<asp:Label ID="nameLabel" runat="server" Text='<%# Eval("name") %>' />
<br />
ip:
<asp:Label ID="ipLabel" runat="server" Text='<%# Eval("ip") %>' />
<br />
</td>
</AlternatingItemTemplate>
<EditItemTemplate>
<td runat="server" style="">name:
<asp:TextBox ID="nameTextBox" runat="server" Text='<%# Bind("name") %>' />
<br />
ip:
<asp:TextBox ID="ipTextBox" runat="server" Text='<%# Bind("ip") %>' />
<br />
<asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="更新" />
<br />
<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="取消" />
<br />
</td>
</EditItemTemplate>
<EmptyDataTemplate>
<table runat="server" style="">
<tr>
<td>未傳回資料。</td>
</tr>
</table>
</EmptyDataTemplate>
<EmptyItemTemplate>
<td runat="server" />
</EmptyItemTemplate>
<GroupTemplate>
<tr id="itemPlaceholderContainer" runat="server">
<td id="itemPlaceholder" runat="server"></td>
</tr>
</GroupTemplate>
<InsertItemTemplate>
<td runat="server" style="">name:
<asp:TextBox ID="nameTextBox" runat="server" Text='<%# Bind("name") %>' />
<br />
ip:
<asp:TextBox ID="ipTextBox" runat="server" Text='<%# Bind("ip") %>' />
<br />
<asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="插入" />
<br />
<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="清除" />
<br />
</td>
</InsertItemTemplate>
<ItemTemplate>
<td runat="server" style="" id="color">
<style type="text/css">
.red {
background-color: red;
}
.mediumseagreen {
background-color: mediumseagreen;
}
</style>
name:
<asp:Label ID="nameLabel" runat="server" Text='<%# Eval("name") %>' />
<br />
ip:
<asp:Label ID="ipLabel" runat="server" Text='<%# Eval("ip") %>' />
<br />
</td>
</ItemTemplate>
<LayoutTemplate>
<table runat="server">
<tr runat="server">
<td runat="server">
<table id="groupPlaceholderContainer" runat="server" border="0" style="">
<tr id="groupPlaceholder" runat="server">
</tr>
</table>
</td>
</tr>
<tr runat="server">
<td runat="server" style="">
<asp:DataPager ID="DataPager1" runat="server" PageSize="200">
<Fields>
<asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" ShowLastPageButton="True" />
</Fields>
</asp:DataPager>
</td>
</tr>
</table>
</LayoutTemplate>
<SelectedItemTemplate>
<td runat="server" style="">name:
<asp:Label ID="nameLabel" runat="server" Text='<%# Eval("name") %>' />
<br />
ip:
<asp:Label ID="ipLabel" runat="server" Text='<%# Eval("ip") %>' />
<br />
</td>
</SelectedItemTemplate>
</asp:ListView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:edtwebConnectionString %>" SelectCommand="SELECT [name], [ip] FROM [edtdata] ORDER BY [name]"/>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ListView1" />
</Triggers>
</asp:UpdatePanel>
</asp:Content>
自己在debug時,發現都是只會跑到ItemDataBound事件而已,
並不會跑到sorting事件裡去排序,所以想請教大大小弟是需要修正哪邊的呢?
你可以在 GetData 方法中新增一個欄位用來存放 ping 狀態,並且在排序時以該欄位排序,這樣就可以達到按照 ping 狀態排序的目的了。下面是修改後的範例程式碼:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ListView1.DataSource = GetData();
ListView1.DataBind();
}
}
private DataTable GetData()
{
DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection("Data Source=LAPTOP-8RO7LF5C;Initial Catalog=edtweb;Integrated Security=True"))
{
using (SqlCommand cmd = new SqlCommand("SELECT ip,name FROM edtdata", con))
{
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
// 新增一個欄位來存放 ping 狀態
dt.Columns.Add("PingStatus", typeof(bool));
foreach (DataRow row in dt.Rows)
{
var pingitems = (string)row["ip"];
// 參考官方 Ping 方式
Ping ping = new Ping();
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
PingOptions options = new PingOptions(64, true);
// Wait 1 seconds for a reply.
int timeout = 1000;
PingReply pingReply = ping.Send(pingitems, timeout, buffer, options);
// 將 ping 結果存到 DataTable
row["PingStatus"] = pingReply.Status == IPStatus.Success;
}
// 以 ping 狀態排序
dt.DefaultView.Sort = "PingStatus ASC, ip DESC";
dt = dt.DefaultView.ToTable();
}
}
return dt;
}
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
System.Data.DataRowView DRV = (System.Data.DataRowView)e.Item.DataItem;
var pingStatus = (bool)DRV.Row["PingStatus"];
var lab = e.Item.FindControl("color") as HtmlControl;
if (!pingStatus)
{
lab.Attributes.Add("class", "red");
}
else
{
lab.Attributes.Add("class", "mediumseagreen");
}
}
}
這樣就可以在 GetData 方法中先用 Ping 將狀態儲存到 DataTable 中,然後再以該欄位排序。在 ListView1_ItemDataBound 事件中,你可以取得該列資料的 ping 狀態並且依據狀態變更該列的背景顏色。
請教一下J大,我後來使用您的方式去用會造成載入網頁很久,下追蹤有發現在 foreach跑多筆ip資料。
小弟後來也使用async方式去非同步,但一直也會載入很久跑不出來,請教一下J大可給個方向或參考的嗎?
都主要在 foreach迴圈裡跑多筆資料遲遲不出來,資料筆數約有2000筆
這個程式中,問題可能在於 ping 要在 foreach 迴圈內運行 2000 次,這會造成每次網頁載入時都需要執行 2000 次的 ping,這可能會花費很長的時間。
可以使用多執行緒來讓 Ping 執行於不同的執行緒,以下是修改後的程式碼範例:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ListView1.DataSource = GetData();
ListView1.DataBind();
}
}
private DataTable GetData()
{
DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection("Data Source=LAPTOP-8RO7LF5C;Initial Catalog=edtweb;Integrated Security=True"))
{
using (SqlCommand cmd = new SqlCommand("SELECT ip,name FROM edtdata", con))
{
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
// 新增一個欄位來存放 ping 狀態
dt.Columns.Add("PingStatus", typeof(bool));
List<Task> pingTasks = new List<Task>();
foreach (DataRow row in dt.Rows)
{
pingTasks.Add(Task.Run(() =>
{
var pingitems = (string)row["ip"];
// 參考官方 Ping 方式
Ping ping = new Ping();
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
PingOptions options = new PingOptions(64, true);
// Wait 1 seconds for a reply.
int timeout = 1000;
PingReply pingReply = ping.Send(pingitems, timeout, buffer, options);
// 將 ping 結果存到 DataTable
row["PingStatus"] = pingReply.Status == IPStatus.Success;
}));
}
Task.WaitAll(pingTasks.ToArray());
// 以 ping 狀態排序
dt.DefaultView.Sort = "PingStatus ASC, ip DESC";
dt = dt.DefaultView.ToTable();
}
}
return dt;
}
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
System.Data.DataRowView DRV = (System.Data.DataRowView)e.Item.DataItem;
var pingStatus = (bool)DRV.Row["PingStatus"];
var lab = e.Item.FindControl("color") as HtmlControl;
if (!pingStatus)
{
lab.Attributes.Add("class", "red");
}
else
{
lab.Attributes.Add("class", "mediumseagreen");
}
}
}