Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Anders Aleborg 35 posts 67 karma points
    Oct 13, 2011 @ 20:28
    Anders Aleborg
    0

    Weird behavior in user control, tick event isn't accessed

    Hi,

    I have made an user control containing a registration form, the user control is inserted in the pages through a macro. In the uer control I have a longrunning process that takes up to 3 minutes, to not bore the visitor to death I have put this in another thread and while it's running I'm displaying a progressbar and information about where in the progress the script is. This is done by having an updatepanel and a timer and a asp:Literal that is updated on "Tick", the progress text is saved in a session. This works in a regular webform like a charm, no problem at all, this webform has the same look, jquery-scripts, css etc as the production system. But when I take this user control and put it into umbraco and execute it the tick event never happens, the updatepanel is updated but the tick event isn't accessed. I don't have any clue on why at all.

    The header of the page contains:

        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
    <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.8.1/jquery.validate.min.js"></script>
    <script type="text/javascript" src="/scripts/jquery.validationengine.js" charset="utf-8"></script>
    <script type="text/javascript" src="/scripts/jquery.validationengine-sv.js" charset="utf-8"></script>
    <script type="text/javascript" src="/scripts/jquery.maskedinput-1.3.min.js"></script>
    <script type="text/javascript" src="/scripts/jquery.updatepanel.js"></script>
    <!--[if lt IE 9]><script type="text/javascript" src="https://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/themes/base/jquery-ui.css" type="text/css" media="all" />
    <link rel="stylesheet" href="/css/ui.themes.jquery.css" type="text/css" media="all" />
    <link rel="stylesheet" href="/css/validationengine.jquery.css" type="text/css"/>

    The user control contains:

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="myTest.ascx.cs" Inherits="MyPlugin.myTest" %>
    <asp:ScriptManager ID="smCreateAccount" runat="server" EnablePartialRendering="true" />
    <script type="text/javascript">
    $(document).ready(function () {
    <% if(Session["CreateProcessActive"]!=null && Session["CreateProcessActive"].ToString()=="1"){ %>
    $('#btnStep3').hide();
    $('#loader').show();
    <% } %>
    });
    </script>
    <div id="loader" class="loader" style="display:none;">
    <img id="img2" src="/media/3921/loading.gif" alt="Laddar" style="margin:20px;"/>
    <asp:Timer ID="tmrCreateAccount" runat="server" OnTick="tmrCreateAccount_Tick" Enabled="false" />
    <asp:UpdatePanel ID="pnlCreateAccount" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
    <p><asp:Literal ID="litCreateAccount" runat="server"></asp:Literal></p>
    </ContentTemplate>
    <Triggers>
    <asp:AsyncPostBackTrigger ControlID="tmrCreateAccount" EventName="Tick" />
    </Triggers>
    </asp:UpdatePanel>
    </div>
    <asp:LinkButton ID="btnStep3"
    CssClass="btn primary large" Text="Confirm" ClientIDMode="Static"
    runat="server" OnClientClick='return $("#bForm").validationEngine("validate");'
    onclick="btnStep31_Click"></asp:LinkButton>

    The code behind

       protected void Page_Load(object sender, EventArgs e)
    {
    if (Session["Done"] != null)
    {
    if (Session["CreateProcessActive"].ToString().Equals("0"))
    {
    //do some stuff
    }
    }
    }
    protected void btnStep31_Click(object sender, EventArgs e)
    {
    tmrCreateAccount.Enabled = true;
    tmrCreateAccount.Interval = 800;
    Session["CreateProcessActive"] = "1";
    ThreadStart ts = new ThreadStart(CreateCustomer);
    Thread th = new Thread(ts);
    th.Start();
    }
    protected void tmrCreateAccount_Tick(object sender, EventArgs e)
    {
    if (Session["CreateProcessText"] != null)
    litCreateAccount.Text = "Process: " + Session["CreateProcessText"].ToString()+"...";

    pnlCreateAccount.Update();

    if (Session["CreateProcessActive"] != null && (Session["CreateProcessActive"].ToString().Equals("0") || Session["CreateProcessActive"].ToString().Equals("ERROR")))
    {
    Session["Done"] ="1";
    tmrCreateAccount.Enabled = false;
    Response.Redirect(Request.Url.AbsolutePath+"?action=done");
    }
    }
    protected void CreateCustomer()
    {
    //this process can take up to 180 seconds
    Session["CreateProcessActive"] = "1";
    Session["CreateProcessText"] = "Creating account";
    // Doing a lot of stuff...
    Session["CreateProcessText"] = "Doing something";
    // Doing a lot of stuff...
    Session["CreateProcessText"] = "Doing anotherthing";
    // Doing a lot of stuff...
    Session["CreateProcessText"] = "Done, redirecting";
    Session["CreateProcessActive"] = "0";
    }

    I know that this code isn't optimal, but after 500 tests and problem solving to find this issue this is what I have for the moment :)
    Any ideas why the tick event isn't accessed? I'm using latest version of umbraco on IIS7,5

  • Anders Aleborg 35 posts 67 karma points
    Oct 13, 2011 @ 20:58
    Anders Aleborg
    0

    Should add that I only have one form-tag on the page.

  • Rodion Novoselov 694 posts 859 karma points
    Oct 13, 2011 @ 21:53
    Rodion Novoselov
    0

    It's very strange that accessing to the Session object from inside the child thread works properly. As a rule of thumb you should never ever try to call any web-specific objects (like HttpContext, HttpSession, HttpApplicationState, etc) from outside the thread of the http request execution. If you need some way to communicate between a child thread and an asp.net thread then you'd better look for something outside an http context - something like a database, a file on the disk or even a static variable.

  • Anders Aleborg 35 posts 67 karma points
    Oct 13, 2011 @ 22:04
    Anders Aleborg
    0

    Yes I know, but it works in the dev environment, and for now it's only a test. But the problem remains, the tick event isn't fired at all

  • Rodion Novoselov 694 posts 859 karma points
    Oct 13, 2011 @ 22:18
    Rodion Novoselov
    0

    That's the worst about such a pattern - it may seem to work :-) A couple years ago I had big time hard days tracking such a bug in legacy code. As it turned out later they read an uploaded file straight from HttpRequest using a child thread. And it seemed to work - but right untill the size of the file was less then the httpRuntime/requestLengthDiskThreshold (omg I even didn't know about this setting before)...

  • Anders Aleborg 35 posts 67 karma points
    Oct 13, 2011 @ 22:20
    Anders Aleborg
    0

    I added some additional code and noticed that it actually is updated, must be the second thread that doesn't update the session.

    So back to drawing and use a database...

    The weird part is that the second thread is executed and actually reads sessions from the first/main thread but setting/updateing sessions from that thread doesn't work

  • Rodion Novoselov 694 posts 859 karma points
    Oct 13, 2011 @ 22:36
    Rodion Novoselov
    0

    And there's yet another very important thing to keep in mind. All code in a child thread always should be wrapped with try-catch. Any unhandled exeption in a child thread lays down the whole IIS application pool - it's a notorious feature that emerged since .NET 2.0 (a breaking change in background thread behaviour). 

  • Anders Aleborg 35 posts 67 karma points
    Oct 13, 2011 @ 22:47
    Anders Aleborg
    0

    I'll have that in mind :)

    Thanks, you made my day!

Please Sign in or register to post replies

Write your reply to:

Draft