|
Rank: Member Groups: Member
Joined: 12/15/2010 Posts: 12
|
Hello gentleman/ladies. Recently I found that I have a problem with EO.Web.Grid control. I have two grids. The first grid is databinded to a datatable and has attached ClientSideOnItemSelected javascript function, which clears the data in the second grid by iterating through items and cells and calling functions cell.setValue(null); cell.refresh(); After the second grid is cleared I'm evaluating a column data on the selected item from the first grid and populate it to the second one with cell.setValue(data) function. The second grid has N columns and fixed number of rows (in this case 7). I found that when I click quickly many times on the first grid and setting data to the second one the allocated memory by Internet Exlorer 8 grows not constantly but approx. with 400KB. In the result of that after several Megabytes of leak when I press the save button, which is attached to a callback pannel becomes an error like: [ArgumentOutOfRangeException: Index and length must refer to a location within the string. Parameter name: length]. When i comment the two statements cell.setValue(data); and cell.refresh(); there is no leak. If I click not many times, leak is not big and save is ok. I'm using latest release published on your site: 2010.0.40.2 The ASP .NET web application is developed with MS Visual Studio 2010 and .NET framework 3.5
Here is a sample page;
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="WebApplication2._Default" %>
<%@ Register assembly="EO.Web" namespace="EO.Web" tagprefix="eo" %>
<!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></title> </head> <body> <form id="form1" runat="server"> <div> <eo:CallbackPanel ID="CallbackPanel1" runat="server" Height="600px" Width="900px" Triggers="{ControlID:Button1;Parameter:}"> <eo:Grid ID="Grid1" runat="server" BorderColor="#828790" BorderWidth="1px" ColumnHeaderAscImage="00050204" ColumnHeaderDescImage="00050205" ColumnHeaderDividerImage="00050203" ColumnHeaderHeight="24" FixedColumnCount="1" Font-Bold="False" Font-Italic="False" Font-Names="Tahoma" Font-Overline="False" Font-Size="8.75pt" Font-Strikeout="False" Font-Underline="False" GridLineColor="240, 240, 240" GridLines="Both" Height="200px" ItemHeight="19" Width="596px" ClientSideOnItemSelected="OnItemSelected"> <FooterStyle CssText="padding-bottom:4px;padding-left:4px;padding-right:4px;padding-top:4px;" /> <ItemStyles> <eo:GridItemStyleSet> <ItemStyle CssText="background-color: white" /> <ItemHoverStyle CssText="background-image: url(00050206); background-repeat: repeat-x" /> <SelectedStyle CssText="background-image: url(00050207); background-repeat: repeat-x" /> <CellStyle CssText="padding-left:8px;padding-top:2px;white-space:nowrap;" /> </eo:GridItemStyleSet> </ItemStyles> <ColumnHeaderHoverStyle CssText="background-image:url('00050202');padding-left:8px;padding-top:4px;" /> <Columns> <eo:RowNumberColumn> </eo:RowNumberColumn> <eo:StaticColumn DataField="TEST_1" HeaderText="TEST_1" Name="TEST_1"> </eo:StaticColumn> <eo:StaticColumn DataField="TEST_2" HeaderText="TEST_2" Name="TEST_2"> </eo:StaticColumn> <eo:StaticColumn DataField="TEST_3" HeaderText="TEST_3" Name="TEST_3"> </eo:StaticColumn> <eo:StaticColumn DataField="TEST_4" HeaderText="TEST_4" Name="TEST_4" Visible="False"> </eo:StaticColumn> </Columns> <ColumnHeaderStyle CssText="background-image:url('00050201');padding-left:8px;padding-top:4px;" /> </eo:Grid> <eo:Grid ID="Grid2" runat="server" BorderColor="#828790" BorderWidth="1px" ClientSideOnItemSelected="OnItemSelected" ColumnHeaderAscImage="00050204" ColumnHeaderDescImage="00050205" ColumnHeaderDividerImage="00050203" ColumnHeaderHeight="24" FixedColumnCount="1" Font-Bold="False" Font-Italic="False" Font-Names="Tahoma" Font-Overline="False" Font-Size="8.75pt" Font-Strikeout="False" Font-Underline="False" GridLineColor="240, 240, 240" GridLines="Both" Height="200px" ItemHeight="19" Width="596px"> <FooterStyle CssText="padding-bottom:4px;padding-left:4px;padding-right:4px;padding-top:4px;" /> <ItemStyles> <eo:GridItemStyleSet> <ItemStyle CssText="background-color: white" /> <ItemHoverStyle CssText="background-image: url(00050206); background-repeat: repeat-x" /> <SelectedStyle CssText="background-image: url(00050207); background-repeat: repeat-x" /> <CellStyle CssText="padding-left:8px;padding-top:2px;white-space:nowrap;" /> </eo:GridItemStyleSet> </ItemStyles> <ColumnHeaderHoverStyle CssText="background-image:url('00050202');padding-left:8px;padding-top:4px;" /> <Columns> <eo:RowNumberColumn> </eo:RowNumberColumn> <eo:StaticColumn DataField="" HeaderText="TEST_1" Name="TEST_1"> </eo:StaticColumn> <eo:StaticColumn DataField="" HeaderText="TEST_2" Name="TEST_2"> </eo:StaticColumn> <eo:StaticColumn DataField="" HeaderText="TEST_3" Name="TEST_3"> </eo:StaticColumn> <eo:StaticColumn DataField="" HeaderText="TEST_4" Name="TEST_4" Visible="False"> </eo:StaticColumn> </Columns> <ColumnHeaderStyle CssText="background-image:url('00050201');padding-left:8px;padding-top:4px;" /> </eo:Grid> <asp:Button ID="Button1" runat="server" Text="Button" /> </eo:CallbackPanel> </div> <script type="text/javascript"> function Grid2_Populate() { var row = 0; for (row = 0; row < 5; row++) { Grid2.addItem(); } } Grid2_Populate(); function OnItemSelected(item) { var row = 0; var col = 0;
for (row = 0; row < 5; row++) { for (col = 0; col < 4; col++) { Grid2.getItem(row).getCell(col).setValue(row*col); } } } </script> </form> </body> </html>
Partial Public Class _Default Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim dt As New DataTable dt.Columns.Add("TEST_1") dt.Columns.Add("TEST_2") dt.Columns.Add("TEST_3") dt.Columns.Add("TEST_4") Dim params(3) As Object For row = 0 To 4
For col As Integer = 0 To 3 params(col) = row * col Next dt.Rows.Add(params) Next
Grid1.DataSource = dt Grid1.DataBind() End Sub
End Class
Click on the first grid and see how IE memory grows, after 10 Megs press the button and see how IE hungs. After several minutes IE shows dialog with message like:
EO.Web Controls Client Side Debug Message EO.Web control 'CallbackPanle1' error message: The callback on 'CallbackPanel1' has failed due to a server side exception. Click OK to see exception message. (set ClientSideOnError to handle this error). You can turn off this message by setting EO.Web.Runtime.DebugLevel to 0 (Not recommended for debug build).
And after pressing the 'OK' button here is the error:
Server Error in '/' Application.
Index and length must refer to a location within the string. Parameter name: length Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentOutOfRangeException: Index and length must refer to a location within the string. Parameter name: length
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[ArgumentOutOfRangeException: Index and length must refer to a location within the string. Parameter name: length] System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy) +7495179 System.String.Substring(Int32 startIndex, Int32 length) +11 EO.Web.Internal.StateDataReader.ReadString() +119 EO.Web.Internal.ik.a(String A_0) +517 EO.Web.Internal.ik.a(String A_0) +535 EO.Web.Internal.ik.a(String A_0) +535 EO.Web.Internal.an.b(String A_0) +250 EO.Web.Internal.an.a(String A_0, String A_1) +1084 EO.Web.Internal.an.a(String A_0, String A_1, String A_2) +85 EO.Web.Internal.an.b(String A_0, String A_1) +39 EO.Web.Internal.bx.aa() +436 EO.Web.WebControlBase.a(Object A_0) +129 EO.Web.CallbackPanel.a(Object A_0) +65 System.Web.UI.Control.LoadViewStateRecursive(Object savedState) +183 System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) +134 System.Web.UI.Control.LoadViewStateRecursive(Object savedState) +221 System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) +134 System.Web.UI.Control.LoadViewStateRecursive(Object savedState) +221 System.Web.UI.Page.LoadAllState() +312 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1661
Version Information: Microsoft .NET Framework Version:2.0.50727.3615; ASP.NET Version:2.0.50727.3618
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
This appears to be a bug. We will look into it and see what we can find.
Thanks!
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
We have looked into the issue and this is not a bug. The reason is the Grid will try to remember all changes you made to it until you explicitly refresh it (by calling DataBind). Internally the Grid maintains a "change log" and a new entry is added into that log every time a change is made. This log for Grid2 accumulates in your sample page and eventually collapse. This is usually not a problem when user makes change manually because it is unlikely user will change that many entries. However it can be a problem when you call setValue to update all cells all the time.
Grid1 does not have this problem because Grid1 is being refreshed in Page_Load every time. You can apply the same idea for Grid2 to avoid the problem. For example, you can get all cell values from Grid2 and save them into a DataTable, then rebind the Grid from that DataTable. That way the Grid still "keeps" all the data but will discard all history logs.
Thanks!
|
|
Rank: Member Groups: Member
Joined: 12/15/2010 Posts: 12
|
Ok, but the customer has very slow internet connection and that's why i load all data into page and OnItemSelect I read hidden column in grid 1, parse the data and populate into grid 2. OnEndEdit in Grid2 i prepare all data from grid 2 and set it to a hidden column of selected item from Grid 1. Just for information in Grid1 may have more than 100 rows (items) and my real grid2 has about 7 columns and 7 rows (items) for each item from Grid1. Even more I have several pageviews (tabs) /4/ with 2 or 3 grids on each pageview with the same functionality. I think the solutions is to provide a way to disable history logs for a grid. Even if we assume that this is normal behavour, I can't appreciate that the error and hung on submit is normal. The point is that the grid works basically at client side driven by javascript. What is your suggestion in that situation? How can we move on?
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
We are not sure what else to suggest rather than refreshing the Grid on the server side. If you keep updating the Grid without explicitly refreshing it, the log will accumulate and it will stop working.
Thanks!
|
|
Rank: Member Groups: Member
Joined: 12/15/2010 Posts: 12
|
And what about if you develop option to disable grid history logs /at design time for example/? Or the other option is to provide a method who will clear history logs at client side?
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
The Grid will not function if we disable the logs. It relies on the log to restore all the changed data on the server side.
Thanks
|
|
Rank: Member Groups: Member
Joined: 12/15/2010 Posts: 12
|
Does it mean that the grid is not developed for effective client side operations with rare postbacks for refreshing? I mean if user sets values in the grid many times without postback, finallly he will overflow buffers and the error will appear, am I right?
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
The Grid is developed for effective client side operations but it's main priority is for user input, not for you to update all cells with code repeatly without refreshing. When you keep updating all the cells you will run into that issue. In your case the simplest solution is to post back to the server and update the Grid. You can do that with AJAX if you do not want to a full post back. If you have to do it your way, then it will not work for you.
This issue is now closed.
Thanks!
|
|