admin管理员组

文章数量:1406937

I have some code like this to update a graph on my page in real-time every 30 seconds:

var counter = 30;

$(function() {
    prepare();
    update();
});

function update() {
    $("#timer").html("Refreshing in " + counter + " seconds...");
    counter--;

    if (counter == 0) {
        counter = 30;
        prepare();
    }

    setTimeout(update, 1000);
}

function prepare() {
    $.ajax({
        type: "POST",
        url: "Service.asmx/GetPlotData",
        contentType: "application/json; charset=utf-8",
        success: OnSuccess, // this function plots the new data
        error: OnError
    });
}

This seems to be working fine except after 16-20 hours of continuously making ajax calls, I get an error back from the server:

Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

I fired up the debug console and this is what I observe:

AJAX calls are getting fired correctly

Before the 16-20 hour period, there are some instances where the latency increase (this is where the Timeout error is seen for the first time)

Finally, the code manages to hit some bottleneck. Latency increases for every single call and the front-end breaks. No call after the blue arrow below returns any data. Instead, it throws the timeout error.

I am sure I am doing something fundamentally wrong. Any ideas on how to address this problem?

EDIT: Server-side code

My connection string:

Data Source={0};Initial Catalog={1};Integrated Security=True;MultipleActiveResultSets=true

The code to pull the records:

try
{
    string ConString = Constants.connString;
    con = new SqlConnection(ConString);

    cmd = new SqlCommand(sql, con);
    con.Open();
    dr = cmd.ExecuteReader();

    while (dr.Read())
    {
        // Add the records into an object
    }

}
catch (Exception x)
{
     // Send back some error text.
     // This is what is giving out the Timeout error
}
finally
{
    con.Close();
}

Unless I am missing something, I am closing the connection after getting the records using the con.Close() or is there anything else I need to do?

EDIT 2: Changing the above code as follows. Is this correct?

try
{
    string ConString = Constants.connString;

    using (con = new SqlConnection(ConString))
    {
        cmd = new SqlCommand(sql, con);
        con.Open();
        dr = cmd.ExecuteReader();

        while (dr.Read())
        {
            // Add rows to object
        }
    }

}
catch (Exception x)
{
    // Handle error
}
finally
{
    con.Close();
}

I have some code like this to update a graph on my page in real-time every 30 seconds:

var counter = 30;

$(function() {
    prepare();
    update();
});

function update() {
    $("#timer").html("Refreshing in " + counter + " seconds...");
    counter--;

    if (counter == 0) {
        counter = 30;
        prepare();
    }

    setTimeout(update, 1000);
}

function prepare() {
    $.ajax({
        type: "POST",
        url: "Service.asmx/GetPlotData",
        contentType: "application/json; charset=utf-8",
        success: OnSuccess, // this function plots the new data
        error: OnError
    });
}

This seems to be working fine except after 16-20 hours of continuously making ajax calls, I get an error back from the server:

Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

I fired up the debug console and this is what I observe:

AJAX calls are getting fired correctly

Before the 16-20 hour period, there are some instances where the latency increase (this is where the Timeout error is seen for the first time)

Finally, the code manages to hit some bottleneck. Latency increases for every single call and the front-end breaks. No call after the blue arrow below returns any data. Instead, it throws the timeout error.

I am sure I am doing something fundamentally wrong. Any ideas on how to address this problem?

EDIT: Server-side code

My connection string:

Data Source={0};Initial Catalog={1};Integrated Security=True;MultipleActiveResultSets=true

The code to pull the records:

try
{
    string ConString = Constants.connString;
    con = new SqlConnection(ConString);

    cmd = new SqlCommand(sql, con);
    con.Open();
    dr = cmd.ExecuteReader();

    while (dr.Read())
    {
        // Add the records into an object
    }

}
catch (Exception x)
{
     // Send back some error text.
     // This is what is giving out the Timeout error
}
finally
{
    con.Close();
}

Unless I am missing something, I am closing the connection after getting the records using the con.Close() or is there anything else I need to do?

EDIT 2: Changing the above code as follows. Is this correct?

try
{
    string ConString = Constants.connString;

    using (con = new SqlConnection(ConString))
    {
        cmd = new SqlCommand(sql, con);
        con.Open();
        dr = cmd.ExecuteReader();

        while (dr.Read())
        {
            // Add rows to object
        }
    }

}
catch (Exception x)
{
    // Handle error
}
finally
{
    con.Close();
}
Share Improve this question edited Oct 8, 2012 at 17:03 Legend asked Oct 8, 2012 at 16:39 LegendLegend 117k123 gold badges284 silver badges406 bronze badges 8
  • 2 keep track of how many calls have been made, you'll probably find it's some "familiar" power-of-2 or power-of-10 number. if that's the case, then you're hitting a browser limit. if it's some random number, then something else is in play – Marc B Commented Oct 8, 2012 at 16:43
  • @MarcB: Thank you. I'll instrument the code. Why exactly is the browser limit ing into play here? At least the initial AJAX calls seem to be pleted just fine or am I missing something else? – Legend Commented Oct 8, 2012 at 16:44
  • I haven't done any 16+hour runtime scripts in a long while, but I do remember that there was some quick in the settimeout stuff that each subsequent self-scheduled timeout added on layer to a call stack. could be something is keeping ghosts of the ajax calls alive in that stack, eventually exhausing the internal pool for such things. – Marc B Commented Oct 8, 2012 at 16:47
  • I think your problem is in the server code, not the client code you posted, that seems fine. – Nelson Benítez León Commented Oct 8, 2012 at 16:48
  • @Nelson: Added the server-side code to my question too. From what I can understand, I am closing the connection after every query to the DB. Do you see anything suspicious? – Legend Commented Oct 8, 2012 at 16:53
 |  Show 3 more ments

2 Answers 2

Reset to default 4

It looks like a server-side issue with too many connections to a database. How're you connecting to the DB? Are you closing the connection after using it? Try closing the connection after a number of connections.

"I get an error back from the server" makes me think this is a server side resource leak. What happens if you run two browser tabs in parallel, or two browsers in parallel, or two hosts with their own browsers hitting the server in parallel?

Does your browser memused rise over time?

If you have access to server side logs, that would also be a point to dive in.

EDIT

After seeing server code, you may want to close the reader as well for safety; I would be surprised if this caused a leak, but you never know. I'm more familiar with Java, where this can cause a leak depending on the underlying driver being used.

dr.Close();
con.Close();

本文标签: javascriptWhat is the right way of making continuous ajax callsStack Overflow