Note that there are some explanatory texts on larger screens.

plurals
  1. POasp.net AJAX best practise for client calling slow async process on server
    primarykey
    data
    text
    <p>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.</p> <p>I have implemented the service as WCF. I generate async methods when I add the service reference to my web client. </p> <p>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.</p> <p>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).</p> <p>I'm doing this mini-project as a learning exercise then I aim to do the same with MVC3 to know the differences.</p> <p>Code Snippet (without separate thread, causing screen rendering to slow down during callback):</p> <pre><code>//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&lt;AsyncWorkCompletedEventArgs&gt;(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); } </code></pre> <p>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:</p> <pre><code> // 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); }); </code></pre> <p>UPDATE:</p> <p>Adding Page Markup as requested:</p> <pre><code>&lt;%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ASForm.aspx.cs" Inherits="Web_Asp_FBMonitor.ASForm" Async="true" EnableSessionState="True" %&gt; &lt;asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server"&gt; &lt;/asp:Content&gt; &lt;asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"&gt; &lt;h2&gt; ASP.NET Connection Test (Client in ASYNC, Server in ASYNC) &lt;/h2&gt; &lt;asp:ScriptManager ID="ScriptManager1" runat="server"&gt; &lt;/asp:ScriptManager&gt; &lt;p&gt; &lt;%--This update panel shows the time, updated every second--%&gt; &amp;nbsp;&lt;asp:UpdatePanel ID="UpdatePanel2" runat="server"&gt; &lt;ContentTemplate&gt; &lt;h3&gt; &lt;asp:Label ID="LabelTime" runat="server" Text=""&gt;&lt;/asp:Label&gt; &lt;/h3&gt; &lt;asp:Timer ID="Timer1" runat="server" Interval="1000" ontick="Timer1_Tick"&gt; &lt;/asp:Timer&gt; &lt;/ContentTemplate&gt; &lt;/asp:UpdatePanel&gt; &lt;/p&gt; &lt;p&gt; &lt;%--This update panel shows our results grid--%&gt; &amp;nbsp;&lt;asp:UpdatePanel ID="UpdatePanel1" runat="server"&gt; &lt;ContentTemplate&gt; &lt;asp:GridView ID="GridView1" runat="server"&gt; &lt;/asp:GridView&gt; &lt;asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Default.aspx"&gt;Client Sync Page&lt;/asp:HyperLink&gt; &lt;br /&gt; &lt;asp:Button ID="ButtonUpdate" runat="server" Text="Update" onclick="ButtonUpdate_Click" /&gt; &lt;/ContentTemplate&gt; &lt;/asp:UpdatePanel&gt; &lt;/p&gt; &lt;/asp:Content&gt; </code></pre> <p><strong>UPDATE 2:</strong></p> <p>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.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload