[CLOSED] Async loading and re-loading of panels in a reporting portal - Suggestions?

Page 2 of 3 FirstFirst 123 LastLast
  1. #11
    This isn't really ASYNC chart loading. Each of the controls loads one after the other as I suspect the direct methods are handled synchronously, if 1 chart were to take 30 seconds to load, then the others have to wait for it to finish. I see this as a big disadvantage over IFrames.
    There is a limitation imposed by the ASP.NET framework that is related to this synchronous loading you are experiencing.

    Please see the following documentation regarding ASP.NET Session State handling during "Concurrent Requests".

    http://msdn.microsoft.com/en-us/library/ms178581.aspx

    Access to ASP.NET session state is exclusive per session, which means that if two different users make concurrent requests, access to each separate session is granted concurrently. However, if two concurrent requests are made for the same session (by using the same SessionID value), the first request gets exclusive access to the session information. The second request executes only after the first request is finished. (The second session can also get access if the exclusive lock on the information is freed because the first request exceeds the lock time-out.) If the EnableSessionState value in the @ Page directive is set to ReadOnly, a request for the read-only session information does not result in an exclusive lock on the session data. However, read-only requests for session data might still have to wait for a lock set by a read-write request for session data to clear.
    What this means, if an individual user makes a call to the Session object, any subsequent requests by that user (even if this occurs in a different Thread) will be handled Synchronously.

    The following sample demonstrates the scenario.

    Example

    <%@ Page Language="C#" %>
    
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    
    
    <script runat="server">
        protected void Button1_Click(object sender, DirectEventArgs e) 
        {
            System.Threading.Thread.Sleep(10000);
            this.Label1.Text = "Label1 : " + DateTime.Now.ToLongTimeString();
        }
    
    
        protected void Button2_Click(object sender, DirectEventArgs e)
        {
            System.Threading.Thread.Sleep(1000);
            this.Label2.Text = "Label2 : " + DateTime.Now.ToLongTimeString();
        }
    
    
        protected void Button3_Click(object sender, DirectEventArgs e)
        {
            System.Threading.Thread.Sleep(5000);
            this.Label3.Text = "Label3 : " + DateTime.Now.ToLongTimeString();
        }
    
    
        protected void Button4_Click(object sender, DirectEventArgs e)
        {
            System.Threading.Thread.Sleep(1000);
            this.Label4.Text = "Label4 : " + DateTime.Now.ToLongTimeString();
        }
    </script>
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Ext.NET Example</title>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
    
    
            <ext:Button runat="server" Text="Submit 1 (10 sec)" OnDirectClick="Button1_Click" />
            <ext:Button runat="server" Text="Submit 2 (1 sec)" OnDirectClick="Button2_Click" />
            <ext:Button runat="server" Text="Submit 3 (5 sec)" OnDirectClick="Button3_Click" />
            <ext:Button runat="server" Text="Submit 4 (1 sec)" OnDirectClick="Button4_Click" />
    
    
            <ext:Label ID="Label1" runat="server" /><br />
            <ext:Label ID="Label2" runat="server" /><br />
            <ext:Label ID="Label3" runat="server" /><br />
            <ext:Label ID="Label4" runat="server" />
        </form>
    </body>
    </html>
    Click each Button, one after another, and you'll notice they return synchronously, with "Button1" having to return before "Button2". This is obviously not the desired result.

    You can work-around the problem by disabling Session State at the Application level, within the Web.config or disabling at the Page level by adding EnableSessionState="ReadOnly" to the @Page directive.

    Example (Web.config)

    <system.web>
        <sessionState mode="Off" />
    </system.web>
    Example (@Page)

    <%@ Page Language="C#" EnableSessionState="ReadOnly" %>
    Re-run the example above and all Button DirectEvents will now return Asynchronously.

    To summarize, ASP.NET imposes a concurrent Thread limitation if Session State is accessed, which appears to happen by default in ASP.NET. This doesn't appear to be specific to any actions Ext.NET is performing.

    Hope this helps.
    Last edited by geoffrey.mcgill; Jan 16, 2012 at 8:11 PM.
    Geoffrey McGill
    Founder
  2. #12
    The "Control with ID ... not found" exception is a different problem, not related to the Session issues from my last post.

    I think we're going to have to make you a new sample, because the way your last sample is configured is not going to work. For DirectEvents to function properly, the UserControl must be re-created earlier in the life-cycle.

    I think it might be better to use DirectMethods instead of DirectEvents, but this will require some testing and the creation of a new sample.

    We should be able to post something later today.
    Geoffrey McGill
    Founder
  3. #13
    I updated the post above regarding Session State. It appears the original issue is not triggered by anything Ext.NET is doing, but is the default functionality of ASP.NET.


    At the moment, the only two options available to work-around this limitation of ASP.NET is to disable Session State at the Web.config level, or set as ReadOnly at the @Page level. Both options are detailed above.

    http://forums.ext.net/showthread.php...ll=1#post72625

    Hope this helps.
    Geoffrey McGill
    Founder
  4. #14
    Hi Geoffrey,

    Thanks for your input, that session state limitation however is further forcing me down the IFrame route. After saying yesterday that I thought that IFrames were async, I noticed that my other prototype (An IFrame version) was exhibiting the same 'queueing' behavior when requesting 4 charts some of which are setup to take a long time to load. However, now you point out that this is a session state limitation, I can see a way around it, the page which I host inside the IFrame can simply be set to have EnableSessionState="ReadOnly", making the 'chart controls' load async, I've tried this and it appears to work as expected, and I can still set variables in session in the main page.

    I don't see a way around that using a single page with XRendered controls, even if the other issues of where I create the controls in the lifecycle can be fixed and the bugs ironed out, I don't think I can make session 'ReadOnly' for the entire reporting portal.

    I've also tried creating and re-creating the controls in OnInit instead of Page_Load, this does seem to fix the issues with the 'Loading' mask, this now appears every time as expected, I've also changed from DirectEvents to DirectMethods however I still get 'control not found errors' (referring now to the control and not the button as the direct method is defined there) when I click the button which calls the DirectMethod, even though that control has been created in the OnInit method.
  5. #15
    Quote Originally Posted by sadaf View Post
    I don't think I can make session 'ReadOnly' for the entire reporting portal.
    If so, there is, seems, a single solution (apart from iframes) - moving the logic to an HTTP handler or Web Service, i.e. to the things which don't use Session.

    There is, though, the limitation - no DirectEvents and DirectMethods within user controls since they will be rendered in an HTTP handler or Web Service and have no relation to a page. But you can use DirectEvents or DirectMethods with an URL referred to an HTTP handler or Web Service and produce a respective JavaScript there. Also please remember many things are possible on client side via JavaScript.
  6. #16
    Hi Daniil,

    Yes, I've got 2 solutions:
    IFrames
    or
    Client side rendering (Java charts/gauges etc)

    Client side rendering would use a javascript webservice call to query for the data after the controls have rendered and draw the charts in javascript. The only problem I've found with this, is that the only decent javascript charting package I could find (which supports everything I wanted) was Sencha Ext JS4!!! That along with the complexity of making all the chart configuration client side and written in Javascript, after some discussion here with my peers I think we will most likely decide to go the IFrame route for this first revision, and hopefully when Ext.Net 2.0 comes out and supports charts and includes Ext JS4 we could improve the solution to use client side java charts.
  7. #17
    Ok, thanks for the update.

    By the way, we have released Ext.NET v2 Developer Preview 1.
    http://forums.ext.net/showthread.php?16883

    It's raw yet to use to develop an application, but the Charts are already there.

    Some of the charts examples:
    https://examples2.ext.net/#/Chart/Bar/Stacked/
    https://examples2.ext.net/#/Chart/Area/Browser_Stats/
  8. #18
    Hi again,

    After further discussion with our architect I'm being asked to re-look at using the Ext.Net method, avoiding IFrames and use of NCache to replace session (so that I can turn session to readonly for the charting pages and gain Async loading).
    Consequently I need some help in making the following prototype work, this is my current prototype with DirectMethod button handlers and control creation in OnInit.

    It has the following problems:
    1) Whenever I click on a button inside a control which fires a directmethod I get... "The control with ID 'xxxx' not found'... even though I AM re-creating and re-adding all the controls in OnInit of the page (but only when ViewState determined that they have been loaded once).

    DashboardXRenderPrototype.aspx
    <%@ Page Language="C#" EnableSessionState="ReadOnly"
     AutoEventWireup="true" CodeBehind="DashboardXRenderPrototype.aspx.cs" Inherits="DevTesting.DashboardXRenderPrototype" %>
    
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <ext:ResourceManager ID="extResourceManager" runat="server" DirectMethodNamespace="CompanyX" />
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
        <script type="text/javascript">
            var loadContainer = function (panel) {
                panel.body.mask('Loading...', 'x-mask-loading');
                CompanyX.LoadContainer(panel.id, panel.containerID, panel.loadTimeSecs, { viewStateMode: 'enabled' });
            };
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <ext:Viewport ID="ViewPortMain" runat="server" Layout="border">
                <Items>
                    <ext:Panel ID="headerPanel" runat="server" Region="North" Title="Header" Height="76">
                        <Content>
                            <ext:Button runat="server" ID="btnReloadAllCharts" Text="Reload All Charts">
                                <DirectEvents>
                                    <Click OnEvent="ReloadAllCharts" />
                                </DirectEvents>
                            </ext:Button>
                        </Content>
                    </ext:Panel>
                    <ext:Panel ID="mainPanel" runat="server" Border="false" Region="Center" BodyStyle="background-color : #e4edfe;">
                        <Content>
                            <ext:BorderLayout runat="server">
                                <West MinWidth="175" MaxWidth="400" Split="true" Collapsible="true">
                                    <ext:Panel Width="175" runat="server" Layout="FitLayout">
                                        <Items>
                                            <ext:Panel ID="Container0" runat="server" Title="XRenderPanel">
                                                <CustomConfig>
                                                    <ext:ConfigItem Name="containerID" Value="0" Mode="Raw" />
                                                    <ext:ConfigItem Name="loadTimeSecs" Value="0" Mode="Raw" />
                                                </CustomConfig>
                                                <Tools>
                                                    <ext:Tool Type="Refresh" Handler="loadContainer(panel);" />
                                                </Tools>
                                                <Listeners>
                                                    <AfterRender Handler="loadContainer(this);" Delay="1"/>
                                                </Listeners>
                                            </ext:Panel>
                                        </Items>
                                    </ext:Panel>
                                </West>
                                <Center>
                                    <ext:Container runat="server" Region="Center" Layout="VBoxLayout">
                                        <LayoutConfig>
                                            <ext:VBoxLayoutConfig Align="Stretch" />
                                        </LayoutConfig>
                                        <Items>
                                            <ext:Container runat="server" Layout="HBoxLayout" Flex="1">
                                                <LayoutConfig>
                                                    <ext:HBoxLayoutConfig Align="Stretch" />
                                                </LayoutConfig>
                                                <Items>
                                                    <ext:Panel ID="Container1" runat="server" Flex="1" Title="XRenderPanel">
                                                        <CustomConfig>
                                                            <ext:ConfigItem Name="containerID" Value="1" Mode="Raw" />
                                                            <ext:ConfigItem Name="loadTimeSecs" Value="0" Mode="Raw" />
                                                        </CustomConfig>
                                                        <Tools>
                                                            <ext:Tool Type="Refresh" Handler="loadContainer(panel);" />
                                                        </Tools>
                                                        <Listeners>
                                                            <AfterRender Handler="loadContainer(this);" Delay="1" />
                                                        </Listeners>
                                                    </ext:Panel>
                                                     <ext:Panel ID="Container2" runat="server" Flex="1" Title="XRenderPanel">
                                                        <CustomConfig>
                                                            <ext:ConfigItem Name="containerID" Value="2" Mode="Raw" />
                                                            <ext:ConfigItem Name="loadTimeSecs" Value="0" Mode="Raw" />
                                                        </CustomConfig>
                                                        <Tools>
                                                            <ext:Tool Type="Refresh" Handler="loadContainer(panel);" />
                                                        </Tools>
                                                        <Listeners>
                                                           <AfterRender Handler="loadContainer(this);" Delay="1" />
                                                        </Listeners>
                                                    </ext:Panel>
                                                </Items>
                                            </ext:Container>
                                            <ext:Container runat="server" Layout="HBoxLayout" Flex="1">
                                                <LayoutConfig>
                                                    <ext:HBoxLayoutConfig Align="Stretch" />
                                                </LayoutConfig>
                                                <Items>
                                                    <ext:Panel ID="Container3" runat="server" Flex="1" Title="XRenderPanel">
                                                        <CustomConfig>
                                                            <ext:ConfigItem Name="containerID" Value="3" Mode="Raw" />
                                                            <ext:ConfigItem Name="loadTimeSecs" Value="5" Mode="Raw" />
                                                        </CustomConfig>
                                                        <Tools>
                                                            <ext:Tool Type="Refresh" Handler="loadContainer(panel);" />
                                                        </Tools>
                                                        <Listeners>
                                                            <AfterRender Handler="loadContainer(this);" Delay="1" />
                                                        </Listeners>
                                                    </ext:Panel>
                                                    <ext:Panel ID="Container4" runat="server" Flex="1" Title="XRenderPanel">
                                                        <CustomConfig>
                                                            <ext:ConfigItem Name="containerID" Value="4" Mode="Raw" />
                                                            <ext:ConfigItem Name="loadTimeSecs" Value="5" Mode="Raw" />
                                                        </CustomConfig>
                                                        <Tools>
                                                            <ext:Tool Type="Refresh" Handler="loadContainer(panel);" />
                                                        </Tools>
                                                        <Listeners>
                                                            <AfterRender Handler="loadContainer(this);" Delay="1" />
                                                        </Listeners>
                                                    </ext:Panel>
                                                </Items>
                                            </ext:Container>
                                        </Items>                                    
                                    </ext:Container>
                                </Center>
                            </ext:BorderLayout>
                        </Content>
                    </ext:Panel>
                </Items>
            </ext:Viewport>
        </div>
        </form>
    </body>
    </html>
    DashboardXRenderPrototype.aspx.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Ext.Net;
    
    namespace DevTesting
    {
        public partial class DashboardXRenderPrototype : System.Web.UI.Page
        {
            protected override void OnInit(EventArgs e)
            {
                //Dynamic controls must be re-created during each request otherwise ext cannot find the direct 
                //method handler, if this is not done then when you fire a direct method from say.. 
                //a button in the user control you'll get the error 'The user control with ID='xxxxx' not found'
                if (this.ViewState[string.Format("{0}HasLoaded", "Container0")] != null)
                    this.CreateControl("Container0", "0");
                if (this.ViewState[string.Format("{0}HasLoaded", "Container1")] != null)
                    this.CreateControl("Container1", "1");
                if (this.ViewState[string.Format("{0}HasLoaded", "Container2")] != null)
                    this.CreateControl("Container2", "2");
                if (this.ViewState[string.Format("{0}HasLoaded", "Container3")] != null)
                    this.CreateControl("Container3", "3");
                if (this.ViewState[string.Format("{0}HasLoaded", "Container4")] != null)
                    this.CreateControl("Container4", "4");
    
                base.OnInit(e);
            }
    
            protected void Page_Load(object sender, EventArgs e)
            {
                System.Diagnostics.Debug.WriteLine(
                string.Format(">Dashboard.Page_Load() = IsPostBack={0},IsAjaxRequest={1}", IsPostBack, X.IsAjaxRequest));
            }
    
            [DirectMethod(ViewStateMode = ViewStateMode.Enabled)]
            public void LoadContainer(string panelID, string containerID, string loadTimeSecs)
            {
                System.Diagnostics.Debug.WriteLine(
                    string.Format(">Dashboard.LoadContainer() = panelID={0},containerID={1}", panelID, containerID));
                            
                DashboardXRenderPrototypeControl uc = this.LoadControl("DashboardXRenderPrototypeControl.ascx") as DashboardXRenderPrototypeControl;
                uc.ID = string.Format("{0}{1}", panelID, containerID);
                uc.PanelID = panelID;
                uc.ContainerID = Int32.Parse(containerID);
                uc.LoadTimeSecs = Int32.Parse(loadTimeSecs);
                Ext.Net.Panel p = Ext.Net.Utilities.ControlUtils.FindControl<Ext.Net.Panel>(this.Form, panelID);
                if (p.ContentControls.Count > 0)
                    p.ContentControls.Clear();
                p.ContentControls.Add(uc);            
                p.UpdateContent();
    
                string key = string.Format("{0}HasLoaded", panelID);
                this.ViewState[key] = true;
                System.Diagnostics.Debug.WriteLine(string.Format("ViewState[{0}]={1}", key, this.ViewState[key]));
            }
    
            public void CreateControl(string panelID, string containerID)
            {
                System.Diagnostics.Debug.WriteLine(
                    string.Format(">Dashboard.CreateControl() = panelID={0},containerID={1}", panelID, containerID));
                
                DashboardXRenderPrototypeControl uc = this.LoadControl("DashboardXRenderPrototypeControl.ascx") as DashboardXRenderPrototypeControl;
                uc.ID = string.Format("{0}{1}", panelID, containerID);
                uc.PanelID = panelID;
                uc.ContainerID = Int32.Parse(containerID);
                Ext.Net.Panel p = Ext.Net.Utilities.ControlUtils.FindControl<Ext.Net.Panel>(this.Form, panelID);
                p.ContentControls.Add(uc);
            }
    
            protected void ReloadAllCharts(object sender, DirectEventArgs e)
            {
                X.Js.Call("loadContainer", new JRawValue("Container0"));
                X.Js.Call("loadContainer", new JRawValue("Container1"));
                X.Js.Call("loadContainer", new JRawValue("Container2"));
                X.Js.Call("loadContainer", new JRawValue("Container3"));
                X.Js.Call("loadContainer", new JRawValue("Container4"));
            }
    
            [DirectMethod]
            public void RefreshContainer(string containerID)
            {
                System.Diagnostics.Debug.WriteLine(
                    string.Format(">Dashboard.RefreshContainer(),containerID={0}", containerID));
    
                int id = Int32.Parse(containerID);
                switch (id)
                {
                    case 0:
                        X.Js.Call("loadContainer", new JRawValue("Container0"));
                        break;
                    case 1:
                        X.Js.Call("loadContainer", new JRawValue("Container1"));
                        break;
                    case 2:
                        X.Js.Call("loadContainer", new JRawValue("Container2"));
                        break;
                    case 3:
                        X.Js.Call("loadContainer", new JRawValue("Container3"));
                        break;
                    case 4:
                        X.Js.Call("loadContainer", new JRawValue("Container4"));
                        break;
                    case 5:
                        this.ReloadAllCharts(null, new Ext.Net.DirectEventArgs(null));
                        break;
                }
            }
    
        }
    }
    
    DashboardXRenderPrototypeControl.ascx
    
    
    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="DashboardXRenderPrototypeControl.ascx.cs" Inherits="DevTesting.DashboardXRenderPrototypeControl" %>
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <ext:Label runat="server" ID="TimeoutText">
    </ext:Label>
    <ext:Label runat="server" ID="LoadText">
    </ext:Label>
    <ext:TextField ID="txtReloadID" runat="server" Text="1">
    </ext:TextField>
    <ext:Button ID="btnReload" runat="server" Text="Reload (Enter 0-5)">
        <Listeners>
            <Click Handler="parent.CompanyX.RefreshContainer(#{txtReloadID}.getValue());" />
        </Listeners>
    </ext:Button>
    <ext:Label runat="server" ID="ReloadBtnClickText">
    </ext:Label>
    <ext:Button runat="server" Text="Test Direct Method" ID="ControlButtonDirectEvent">
        <Listeners>
            <Click Handler="#{DirectMethods}.ControlDirectMethod();" />
        </Listeners>
    </ext:Button>
    DashboardXRenderProrotypeControl.ascx.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Ext.Net;
    
    namespace DevTesting
    {
        public partial class DashboardXRenderPrototypeControl : System.Web.UI.UserControl
        {
            public string PanelID { get; set; }
            public int ContainerID { get; set; }
            public int LoadTimeSecs{ get; set; }
    
            protected void Page_Load(object sender, EventArgs e)
            {
                System.Threading.Thread.Sleep(TimeSpan.FromSeconds(LoadTimeSecs));
    
                string s = string.Format("{1} Container={2} Page_Load> @ {0}", DateTime.Now.ToString("hh:mm:ss.fff"), this.ID, this.ContainerID);
                System.Diagnostics.Trace.WriteLine(s);
                this.LoadText.Text = string.Format(s);
    
                this.TimeoutText.Text = string.Format("LoadTimeSecs={0}", this.LoadTimeSecs);
            }
    
            protected void Page_PreRender(object sender, EventArgs e)
            {
                X.Js.AddScript(string.Format("{0}.body.unmask();", this.PanelID));
            }
    
            [DirectMethod]
            public void ControlDirectMethod()
            {
                string s = string.Format(">ControlDirectMethod @ {0}, ID={1}", DateTime.Now.ToString("hh:mm:ss.fff"), this.txtReloadID.Value);
                System.Diagnostics.Trace.WriteLine(s);
                this.ReloadBtnClickText.Text = s;
            }
    
        }
    }
  9. #19
    actually, not wait, I think I see the problem the controls aren't being created because the direct method call from the control doesn't include the viewstate...
  10. #20
    But, no matter what I do,

    call the direct method like so:

    <ext:Button runat="server" Text="Test Direct Method" ID="ControlButtonDirectEvent">
        <Listeners>
            <Click Handler="#{DirectMethods}.ControlDirectMethod({ viewStateMode: 'enabled' });" />
        </Listeners>
    </ext:Button>
    and add

    [DirectMethod(ViewStateMode = ViewStateMode.Enabled)]
    to the method declaration, it looks like ViewState ISN'T being passed to the OnInit method, it isn't present, so the controls aren't re-created...
    Do you have any idea why that might be?
Page 2 of 3 FirstFirst 123 LastLast

Similar Threads

  1. Replies: 4
    Last Post: Nov 03, 2011, 7:46 PM
  2. [CLOSED] Height Issues when auto loading panels
    By craig2005 in forum 1.x Legacy Premium Help
    Replies: 19
    Last Post: Mar 21, 2011, 8:04 PM
  3. Replies: 7
    Last Post: Jul 16, 2010, 12:02 AM
  4. Replies: 6
    Last Post: Mar 12, 2010, 1:34 AM
  5. Replies: 0
    Last Post: Oct 07, 2009, 4:10 AM

Tags for this Thread

Posting Permissions