客户端调用服务器慢的异步处理asp.net AJAX的最佳实践 [英] asp.net AJAX best practise for client calling slow async process on server

查看:112
本文介绍了客户端调用服务器慢的异步处理asp.net AJAX的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有执行缓慢的任务,当其完成我想更新使用AJAX与任务的结果的客户机的服务。在我的客户我调用任务多次更新结果的网格。为了理解的目的,它的连接测试仪来遍历连接列表,看看他们是否还活着。

I have a service that performs a slow task, when its finished I want to update the client using AJAX with the result of the task. In my client I call the task many times to update a grid of results. For the purposes of understanding, its a connection tester that loops through a list of connections to see if they are alive.

我已经实现了服务为WCF。我生成当我添加服务引用到我的Web客户端异步方法。

I have implemented the service as WCF. I generate async methods when I add the service reference to my web client.

在code正常工作,但是在屏幕锁定时,瞬间的回调火 - 我想这是因为他们都出现一前一后,并在接二连三所有的人都重新绘制的GridView控件。 我不希望这种故障的发生 - 我希望AJAX的实施将能够部分地更新的GridView的结果来自该服务通过后面的回调。

The code works fine, however the screen locks momentarily when the callbacks fire - I think this is because they all happen one after the other and all of them repaint the GridView within quick succession. I don't want this glitch to happen -I was hoping the AJAX implementation would be able to partially update the GridView as results come back from the service via the callbacks.

我可以让这个看起来不错,唯一的办法是启动异步调用在一个单独的客户端线程,然后用一个定时器将数据重新绘制到电网(这是作为一个在单独的线程中通过回调更新相同的数据)

The only way I can make this look nice is to launch the async calls in a separate client thread and then use a timer to repaint the data to the grid (the same data that's being updated in the separate thread via the callbacks).

我在做这个小项目作为一个学习锻炼,然后我的目标是与MVC3知道差异做同样的。

I'm doing this mini-project as a learning exercise then I aim to do the same with MVC3 to know the differences.

code片段(不含独立的线程,从而造成屏幕呈现回调过程减慢):

Code Snippet (without separate thread, causing screen rendering to slow down during callback):

//get list of connections from session
ConnectionList myConns = Session[SESSION_ID] as ConnectionList;
//pass into async service call
GetAllStatusAsync(myConns);


protected void GetAllStatusAsync(ConnectionList myConns)
{

Service1Client myClient = new WcfConnectionServiceRef.Service1Client();
myClient.AsyncWorkCompleted += new EventHandler<AsyncWorkCompletedEventArgs>(myClient_AsyncWorkCompleted);

foreach (ConnectionDetail conn in myConns.ConnectionDetail)
  {
  //this call isnt blocking, conn wont be updated until later in the callback
  myClient.AsyncWorkAsync(conn);
  }
}

//callback method from async task
void myClient_AsyncWorkCompleted(object sender, AsyncWorkCompletedEventArgs e)
{

ConnectionDetail connResult = e.Result;

//get list of connections from session
ConnectionList myConns = Session[SESSION_ID] as ConnectionList;

//update our local store
UpdateConnectionStore(connResult, myConns);

//rebind grid
BindConnectionDetailsToGrid(myConns);

}

现在的问题是 - 这可以在一个更好的办法在asp.net / AJAX做了什么? (为了避免渲染锁定的问题,并得到了网格部分更新的结果进来),我真的不希望使用一个单独的客户端线程,如下面的代码片断:

The question is - can this be done in a better way in asp.net / AJAX? (To avoid the rendering lock up problems and get the grid partially updating as results come in) I don't really want to use a separate client thread such as the following snippet:

 // Perform processing of files async in another thread so rendering is not slowed down 
 // this is a fire and forget approach so i will never get results back unless i poll for them in timer from the main thread
ThreadPool.QueueUserWorkItem(delegate
  {
  //get list of connections from session
  ConnectionList myConns = Session[SESSION_ID] as ConnectionList;
  //pass into async service call
  GetAllStatusAsync(myConns);
  });

更新:

添加页面标记的要求:

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ASForm.aspx.cs" Inherits="Web_Asp_FBMonitor.ASForm" Async="true" EnableSessionState="True" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>
        ASP.NET Connection Test (Client in ASYNC, Server in ASYNC)
    </h2>

    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>


    <p>

        <%--This update panel shows the time, updated every second--%>    
        &nbsp;<asp:UpdatePanel ID="UpdatePanel2" runat="server">
        <ContentTemplate>

            <h3> <asp:Label ID="LabelTime" runat="server" Text=""></asp:Label>  </h3>
            <asp:Timer ID="Timer1" runat="server" Interval="1000" ontick="Timer1_Tick">  </asp:Timer>

            </ContentTemplate>
    </asp:UpdatePanel>
    </p>

    <p>

        <%--This update panel shows our results grid--%>
        &nbsp;<asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>

            <asp:GridView ID="GridView1" runat="server">
            </asp:GridView>

            <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Default.aspx">Client Sync Page</asp:HyperLink>

            <br />

            <asp:Button ID="ButtonUpdate" runat="server" Text="Update" 
                onclick="ButtonUpdate_Click" />
        </ContentTemplate>
        </asp:UpdatePanel>




    </p>



</asp:Content>

更新2:

我在找这个简明的客户端JS的例子。接收到的选项是好的,都得到了极大的AP preciated但是客户端JS是一个我通过我自己的经验不足和有点吃力将授予该赏金。

I'm looking for a concise client side JS example of this. The received options are good and have been greatly appreciated but the client side JS is the one I am stuggling with through my own inexperience and will be awarding the bounty for this.

推荐答案

你看你叫什么,因为ASP的屏幕锁定的UpdatePanel 秒。

You see what you call "screen locks" because of the ASP UpdatePanels.

ASP.NET WebForms的是试图使像Windows窗体的网络行为。令人敬佩?取决于你问的是谁。

ASP.NET WebForms are an attempt to make the web act like Windows forms. Admirable? Depends on who you ask.

当您使用的UpdatePanel ,ASP.NET存储在的ViewState 服务器端控件,使得任何改变该视图状态是必要的(在你的情况,这是更新的基础上code在 Timer_Tick ButtonUpdate_Click 函数)。然后,刷新这个新数据的页面,从而导致您所描述的屏幕锁。

When you use an UpdatePanel, ASP.NET stores the server-side controls in ViewState, makes any changes to that ViewState that is necessary (in your case, it's updating the page based on code in your Timer_Tick and ButtonUpdate_Click functions). Then, it refreshes the page with this new data, causing the screen locks you describe.

要解决这个问题,你必须使用真正的AJAX。很多人为此与jQuery的AJAX功能和下列选项之一:

To get around this, you'll have to use real AJAX. A lot of people do this with jQuery AJAX functions and one of the following options:

  • 在ASP.NET的WebMethods
  • WCF服务
  • 在单独的ASP.NET页面

有相当多的问题,在这里因此,关于通过jQuery挂钩ASP.NET的WebMethods了,一些关于装载ASP.NET页面,而不是许多人对AJAX和WCF的问题。

There are quite a few questions here on SO about hooking ASP.NET WebMethods up via jQuery, and some about loading ASP.NET pages, but not as many questions about AJAX and WCF.

如果您选择使用AJAX和jQuery,你的结果页面看起来是这样的:

If you choose to use AJAX and jQuery, your resulting page would look something like this:

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ASForm.aspx.cs" Inherits="Web_Asp_FBMonitor.ASForm" Async="true" EnableSessionState="True" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
<!-- include jQuery library here -->
<script language="javascript" type="text/javascript">
    $(document).ready(function () {
        UpdateGrid();

        // Separate AJAX call to another page, WCF service, or ASP.NET WebMethod for the Timer results
    });

    function UpdateGrid() {
        $.ajax({ url: "GridViewResults.aspx",
            done: function (result) {
                $("#gridResults").html(result.d);
            }
        });
    }
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>
        ASP.NET Connection Test (Client in ASYNC, Server in ASYNC)
    </h2>

    <p>
        <h3> <span id="timer"></span> </h3>
    </p>

    <p id="gridResults">
    </p>
    <button id="ButtonUpdate" onclick="UpdateGrid();">Update</button>
</asp:Content>

然后,在单独的页面(我随意把它叫做 GridViewResults.aspx 以上),你就必须:

Then, on a separate page (I arbitrarily called it GridViewResults.aspx above), you'd have:

<asp:GridView ID="GridView1" runat="server"></asp:GridView>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Default.aspx">Client Sync Page</asp:HyperLink>
<br />

这篇关于客户端调用服务器慢的异步处理asp.net AJAX的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆