I am dynamically creating a table of checkboxes on my test.aspx page. The dimensions (row and column count) of the table are determined by querying the database.
In test.aspx page, I do the following:
<script language="C#" runat="server">
protected void Page_Load ( object src, EventArgs e ) {
//Query the database to get the data for rows and columns
CheckBox[] chkBox = new CheckBox[rows * columns]; //creates a collection of checkboxes
//Iterate over the query set in a double for loop to create dynamic checkboxes
}
</script>
Right now I have the number of rows=20 and columns=10, but it can increase (with the columns more likely).
I used the Net tab in Firebug to ascertain the time taken by different events and found that GetTest.aspx is taking close to 4 minutes, which is too long a time to wait.
Is there a way to being down the page load time? Is my approach to create dynamic check boxes correct?
Thanks in advance.
cheers
I'm looking at this comment:
// Query the database to get the data for rows and columns
You gloss over this, but 9 times out of 10 when a web page loads slowly it's because it's performing some slow database operation.
My guess is that either (a) you have a very inefficient database query, perhaps due to a lack of indexing, or (b) you're running a database query inside a loop somewhere (very bad).
ASP.NET can create thousands of checkboxes in less than 1 second. It's just class instantiation. The issue is somewhere else.
Enabling ASP.NET trace on the page and see where all the time is spent. Four minutes is of course way too long for any page. You list two though... test.aspx and GetTest.aspx... what is GetTest.aspx?
EDIT:
OK, you are not telling us the whole story here. What else is this page doing? Where are these controls going? I just tried this on a test page using code similar to that above and it renders in a split second.
Like I said... enable TRACE and find out what is really taking up all the time! Use the tool, that's why it's there.
Creation of controls (CheckBox) and adding to a holder from the server-side is very inexpensive. Considering you are not creating billions.
The HTML that is generated should not be big enough to take 4 minutes on a local machine.
Please check the generated HTML size to verify its mass.
If I were you then I would have written the following code on my server. Please consider.
protected void Page_Load(object src, EventArgs e) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
holderPanel.Controls.Add(
new CheckBox {
ID = string.Format("chk{0}{1}", i, j),
Text = "some text"
});
}
}
}
Consider the holderPanel is a server side asp:Panel or a simple Div with ID = "holderPanel" and runat="server"
Try disabling Firebug & see if it still takes that long. Also double check that your code didn't generate more checkboxes than you expected.
Related
I am asked to develop an application where a member can select 1 plan, a combination of plans, all plans, or none.
plan1, plan2, plan3, .... plan12
I ran the truth table to find out how many possibilities there are, and it turned out to be 4096. (Ridiculous!)
My plan was to write an if statement for each possibility like this:
if (plan1.Checked == true && plan2.Checked == false && ... && plan12.Checked == false){
// insert into into table test VALUES('Plan1')
}
and so on! Obviously, there must be a better and easier way than this. Any suggestions would help. Thank you all.
If you used a CheckBoxList or similar component this would be one approach.
CheckBoxList checkBoxList = ....; // Just an example here
// You would add the different project names into the CheckBoxList
String message = "";
for (int i = 0; i < checkBoxList.Items.Count; i++) // Look at every project name
{
if (checkBoxList.Items[i].Selected) // See if it's selected
{
message += checkBoxList.Items[i].Text; // Add the name to the message
}
}
Put message in DB; // <-- Store the message into your database here
Since you're only interested in selected items you wouldn't have to deal with non-selected items at all.
Note: There is probably a better/more efficient way of creating strings than this and you might be able to use lambda expressions. This is just showing a simple approach.
Andrew_CS answer is suitable and I prefer it, but here is another way:
Handle the checked event in the code behind of all checkboxes (use one event, but allow all checkboxes to be handled by it), and depending on the sender, then you can load the information you want.
It may be that you use a Select statement to load the relevant information for each checkbox during the checkbox checked event (might be a little easier to understand than a for loop!)
I have the following C# code:
Application["CountTrackViews"] = int.Parse(Application["CountTrackViews"].ToString()) + 1;
The problem here is that there is no start value for this application object, and I really don't know which start value should I give, and how can I do it (this application object should count time of views)
Wish for help, thanks!
If you can add a Global.asax and use the Application_Start event, then you can initialize the value there. Something like this:
protected void Application_Start()
{
Application["CountTrackViews"] = 0;
}
Failing that, you could check for the existence of the value before using it. Something like this:
var viewCount = 0;
int.TryParse(Application["CountTrackViews"], out viewCount);
Application["CountTrackViews"] = viewCount + 1;
This is untested code, you might need to tweak it a little. But the idea is simple enough. Start with a default value, try to parse the current value, if the parsing fails then default to the default value. Wrap all of this in some kind of global (static) helper method so you don't have to repeat these lines in multiple places.
Keep in mind, however, as stated in the comments above that this counter will reset any time the application resets.
This is a bad way of logging page views over any time period longer than 20 minutes. By default in IIS, the application will be recycled after 20 minutes of inactivity. Then your counter will be lost and reset the next time a user loads it.
As David suggested, look to storing this in a database or even text file.
Problem Summary:
I have one page having a textbox and a button.
On Clicking button it read few XMLs and get the following data.
Gets the list of database connectors to connect. A, B, C
Gets the list of queries linked to each connector. A[0,1,2], B[0], c[0, 1, 2, 4]
Now iterate though each database connector, connect, run each query, fetch data, create dynamic controls and panels and display in this fashion.
---A----
Gridview A[0] results
Gridview A[1] results
Gridview A[2] results
---B---
Gridview B[0] results
It works and displays properly if I try synchronously, connecting the connectors one by one. The page freezes for few seconds, but at the end when all operation is complete it displays properly. Problem happens when any of the connector is down. Example. If A is down then till we get the connector Timeout message, B and C also wait and page loading time increases.
Now there is a business demand that this should run Asynchronously, that means all the connectors should be connected and queried simultaneously like parallel. I tried to implement this by using WebService. But in vain. The Div created and closes and then the grid/data is populating. Since the divs are creating dynamically I have no clue how to place the gridviews in those divs.
My current logic is:
Loop through Connectors {
Create <Div class="Container">
Create <Div class="conLabel">Label</div>
Loop through Queries for this connector {
WebSevice _WS = new WebService();
__WS.GetDataCompleted += new GetDataCompletedEventHandler(__WS_GetDataCompleted);
__WS.GetDataAsync(Parameters Here);
}
Create </Div>
}
void __WS_GetDataCompleted(object sender, GetDataCompletedEventArgs e) {
Get result here from e.Result
Create New gridview and bind to it.
}
It displays like this.
---A----
---B---
Gridview A[0] results
Gridview A[1] results
Gridview A[2] results
Gridview B[0] results
I am not sure if this is the right approach or not. I am very new to WebService. How do i create a gridview in some div which itself is created dynamically.
Can someone help me finding any other approach to solve this problem.
I solved this by adding a ASP.NET Panel instead of creating dynamic literal control as .
Loop through Connectors {
Panel myPanel = new Panel();
myPanel.ID = "UNIQUEID"; // Using this ID i am identifying the container
Loop through Queries for this connector {
WebSevice _WS = new WebService();
__WS.GetDataCompleted += new GetDataCompletedEventHandler(__WS_GetDataCompleted);
__WS.GetDataAsync(Parameters Here);
}
}
i created web page with dropdownlist and two gridview and on selectedindex changed event i fill the both of these gridview but in the running the both of gridview take long time to be filled.
Note:one of this gridview i created its datasource by code.
here my code snippet:
protected void _ddlPLCs_SelectedIndexChanged(object sender, EventArgs e)
{
DataTable dtStatus = new DataTable();
dtStatus = DBLayer.getMachineNameIPStatusPlCByName(_ddlPLCs.SelectedValue);
dtStatus.Columns.Add("Status", typeof(String));
foreach (DataRow row in dtStatus.Rows)
{
if (LogicLayer.checkmachineStatus(row["machineIP"].ToString()))
row["Status"] = "Online";
else
row["Status"] = "offline";
}
GVStatus.DataSource = dtStatus;
GVStatus.DataBind();
if (_ddlPLCs.SelectedValue.Contains('-'))
{
_dsPLCs.SelectParameters.Clear();
_dsPLCs.SelectParameters.Add("PLCID","0");
_dsPLCs.DataBind();
}
else
{
_dsPLCs.SelectParameters.Clear();
_dsPLCs.SelectParameters.Add("PLCID", DBLayer.getPlCIDByName(_ddlPLCs.SelectedValue).ToString());
_dsPLCs.DataBind();
}
}
pleas help me
Looking at the code, I think the problem is in this method:
LogicLayer.checkmachineStatus()
I have a hunch that this actually makes a network request to remote machines/devices to determine their status. This is going to be slow, especially if you have machines that might not be online and you have to wait for them to timeout.
If this is the culprit, what you want to do instead is build a service that runs on your server. The service should continually make these checks in the background and update a database table with the results. You probably want to include a timestamp for the last check in the table. It might even be worth inserting rather than updating, so that you have history of when status's were at different values. Your ASP.Net code should then just show the database table.
Profile! Get a trial version of RedGate ANTS and run it against your code.
If you choose line level timings, it will put a number next to each line in the code that will tell you exactly how long each line takes as a % or in milliseconds. Make sure to use wall clock time not cpu time or wait time from your datasource won't be counted properly.
I'd bet your datasource is slow.
You're doing a lot of work here...
A few random thoughts
Networks can be slow -- #Joel had a good point on that one.
One thing to check would be postback -- make sure you're only databinding on selected index changed.
Why aren't you using a 'handles' caluse in your function? Might not be a problem, just curious.
If you change your "status" column header to "online", and then use checkboxes (checked = online, unchecked = off-line, or something like that, you'll just be updating a bool value for each row, instead of a string value.
Something looks odd about how you're re-binding your dropdownlist. Because... You're using the selected value as a parameter in the gridview. Then you're subsequently re-binding the dropdown list, which potentially will result in a different selected value. Which could be causing your gridview to be databound yet again in a circuit. Not sure, as I can't see all of your code.
Anyway, FWIW. Good luck.
im really new to ASP.Net and still havnt got my head round most of the concepts, im really having problems with variable, when creating a desktop application, any variable created in code for example
int n = 10;
this variable will be there until the program is running right. but in asp iv created variables which are supposed to last until the user gets of that page, so for example say i have a page which takes the users value ( call this variable n say the user type in 10) and every time the user presses the next button the code add 10 to this value. so the first time the user presses the next button
n= n + 10;
what i have found is no matter how many times i press the next button n will always equal 20, because the previous value is not saved !!
these values are populated the first time the user enters that page, once the user clicks the next button the content of these values disappear! how can stop this from happening ??
hope this makes sense !!
thanks
Every time you refresh page (click also refreshes page) new instance of Page class is created. This means that all your fields become empty.
You can try to use ViewState to persist data between refreshes. But you should be care as this will increase page size. So best practice is to minimaze data in view state.
Another options is SessionState, but in this case you will keep data even between pages.
Hope this helps.
Each time the user requests the page, it receives the request, is initialized, processed, and then rendered (read about the Asp.Net Page Life Cycle here.). So, on each page request, your variables are being created, initialized, and then assigned your values - each page load is a new life cycle. If you want values to persist betwen page life cycles, then you need to use one of the available methods (ViewState, Session, QueryString, Post, ....) to pass the values to the "next" request.
Variables don't automatically maintain state across page calls in ASP.NET. Asp.Net Page has a life cycle and being stateless, the information is lost at the end of this cycle, after a request has been served on the client side. There are several solution for this.
session
hidden fields
querystrings
Here is hidden field example.
In HTML, you simply create:
<input type="hidden" id="myHiddenVar">
To set it's value in javascript:
document.getElementById("myHiddenVar").value = "myValue"
In ASP.NET code-behind, you use the Request object to retrieve the value.
string myHiddenVar = (string)Request.Params["myHiddenVar"];
Variables in ASP.NET work exactly the way that variables in Windows Forms work:
public class MyPage : System.Web.UI.Page
{
private int n = 0;
public void Button_Click(object sender, EventArgs e)
{
n = n + 1;
}
}
public class MyForm : System.Windows.Forms.Form
{
private int n = 0;
public void Button_Click(object sender, EventArgs e)
{
n = n + 1;
}
}
So, why is it with the page, that the old value of "n" is gone the next time you hit the page?
Because HTTP is a request/response protocol. Each request creates a new instance of your MyPage class, each with its own copy of "n". In a Windows Forms application, you're probably not creating a new instance of your form on every button click!