如何异步加载来自多个源的ASP.NET GridView?

时间:2010-01-01 20:03:01

标签: c# asp.net multithreading gridview asynchronous

情况如下。我需要点击~50台服务器并从文件中获取一些数据。然后,我想在ASP.NET GridView控件中为每个显示几行。

我尝试使用Threads / ThreadPool执行此操作,并成功收集会话中的所有数据。

我想做的事情,以及我很难搞清楚的事情,就是在每个服务器加载完毕后为用户更新网格。

如果我将数据绑定代码放在线程中,它将只显示响应发送回客户端时加载的内容。如果我把它从线程中删除,我将不得不等到所有线程完成后才发送响应,而这不符合我的要求。

有人有什么想法吗?我看到了Asynchronous Client Callbacks的一些内容,但我不确定这是否是我需要使用的内容。我不知道如何从Javascript操作GridView。

感谢您提供的任何帮助。

4 个答案:

答案 0 :(得分:3)

服务器端ASP.NET代码无法使用Web浏览器并告诉它有可用的新数据。因此,您必须使用JavaScript来轮询服务器以获取新数据。有很多方法可以做到这一点。一个例子是在服务器端使用Page Methods,它可以告诉客户端是否有更多可用数据以及何时加载了所有数据。

[WebMethod]
public static bool IsNewDataAvailable(int currentClientRows)
{
    return dataCollectedSoFar.Count > currentClientRows;
}

[WebMethod]
public static bool IsFinished()
{
    // return true if all the threads in the thread pool are finished
}

您需要定期调用IsNewDataAvailable方法。一个简单的JavaScript计时器应该可以解决问题。

当有新数据可用时,您需要重新渲染GridView。同样,有不止一种方法可以做到这一点,但一个简单明了的方法是将GridView放在一个带有style =“display:none;”的Button旁边的UpdatePanel里面。属性以保持隐藏。然后,如果有新数据可用,只需调用按钮上的JavaScript单击方法即可更新更新面板的内容。

<script>
var timerId = setInterval("checkForData()", 5000);

function checkForData() {

    // If all threads have finished, stop polling
    if (PageMethods.IsFinished()) {
        clearInterval(timerId);
    }

    var currentRowCount = 0;

    // Find out how many rows you currently have, if 
    // you have jQuery you could do something like this
    currentRowCount = $("#<%= myGridView.ClientID %> tr").length;

    if (PageMethods.IsNewDataAvailable(currentRowCount)) {

        // Here we trigger the hidden button's click method, again
        // using a bit of jQuery to show how it might be done
        $("#<%= myHiddenButton.ClientID %>").click();
    }
}
</script>

. . .

<asp:UpdatePanel ID="myUpdatePanel" runat="server">
    <ContentTemplate>
        <asp:GridView ID="myGridView" runat="server">
            . . .
        </asp:GridView>
        <asp:Button ID="myHiddenButton" runat="server" style="display: none;" OnClientClick="myHiddenButton_Click" />
    </ContentTemplate>
</asp:UpdatePanel>

最后,要在服务器端填充GridView,您可以继续使用ThreadPool并只渲染每次所有数据。例如:

protected void myHiddenButton_Click(object sender, EventArgs e)
{
    myGridView.DataSource = dataCollectedSoFar;
    myGridView.DataBind();
}

答案 1 :(得分:0)

我很少使用ASP.net控件,所以我很难回答这个问题。我会说我会使用Ajax让客户端知道何时在每个服务器的数据检索完毕后重新加载Gridview。

我确实读过一些名为active widgets的内容,它会取代你的gridview。

以下是我将如何处理这个问题:在初始构建时,提供一个事件机制,该机制在每个服务器的加载任务完成时触发,并将结果存储到会话中。在客户端,只要并非所有服务器请求都完成,就继续更新对象。一个很好的数据格式是JSON。

无论如何,我希望这有所帮助。

答案 2 :(得分:0)

您可以使用gridview放入UpdatePanel并从那里处理客户端回调,这可能是gridview最简单的实现。基本上你只需用一个更新面板包装gridview,里面的任何东西都可以使用ajax。您可以编写有效的代码来查询数据,但ui应该更容易。

您可以使用Javascript和JSON以及客户端Web服务手动完成所有操作,但我会首先尝试更新面板。

答案 3 :(得分:0)

protected void load_Click(object sender,EventArgs e)     {         sqc.ConnectionString = dbc.sqlconn();         sqc.Open();         OleDbCommand cmd = new OleDbCommand(“SELECT cus_serial,cus_name,cus_mobile,no_person,unit_cost,total_cost from booking”,sqc);         // OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);

    sdr = cmd.ExecuteReader();
    DataTable dt = new DataTable("A");
    dt.Load(sdr);
    GridView1.DataSource = dt;
    GridView1.DataBind();
    sdr.Close();
    sqc.Close();
}