Solved

using a thread to call my function

Posted on 2008-10-01
11
1,181 Views
Last Modified: 2011-09-20
Hi,

I havent really used threads before so need a bit of help.

I have a button that when click will basically call a stored procedure that will take a long time to run around 30 mins due to the processing it will do.

I have a user interface to do this.

On the button click I have the function below.

What I am basically trying to do is display the page to show the process is running and then start the thread calling my function that exectues the upload.

The function is as follows:

Private Sub ExecuteUpload()
        Try
            'CLDataAccess.ExecuteNonQuery(_strUploadStoredProcedureName)

            'Once the thread has finished we need to display this to the user and amend the user interface accordingly.
            DisplayPageInUploadedStatus()
        Catch ex As Exception
            Throw
        End Try

I have commented the call to the stored proc out at the moment.

But once the stored proc has finished I want the page to then be updated with details stating it has finished etc.

The ExecuteUpload is being hit but it doesnt seem to be stepping into the try block to hit the function DisplayPageInUploadedStatus.

Can anyone see why?

Is my logic ok in that once the stored proc has finished running the thread will call my function to update the page to say it has finished?

Thanks in advance.


Protected Sub btnStartUpload_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnStartUpload.Click

        Dim uploadThread As Thread
 

        Try

            SetRequiredUpload()
 

            DisplayPageInUploadingStatus()
 

            'set execution running in its own thread

            uploadThread = New Thread(AddressOf ExecuteUpload)

            uploadThread.Start()
 

        Catch ex As Exception

            Throw

        End Try

Open in new window

0
Comment
Question by:scm0sml
  • 7
  • 4
11 Comments
 
LVL 18

Accepted Solution

by:
carlnorrbom earned 500 total points
ID: 22614352
Hi,

For reference on how to adress background worker threads and updating the webform UI, please refer to the attached code as an example.

/Carl.
WorkerThreadPage.aspx:
 

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="WorkerThreadPage.aspx.vb" Inherits="WorkerThreadPage" %>
 

<!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>Background Worker Thread Test</title>

</head>

<body>

    <form id="form1" runat="server">

    <asp:ScriptManager ID="ScriptManager1" runat="server">

    </asp:ScriptManager>

    <div style="border: Solid 1px Gray;padding: 5px 5px 5px 5px;margin-top: 50px;">

        <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="False">

            <ContentTemplate>

                <div id="processDiv" runat="server">

                </div>           

            </ContentTemplate>

            <Triggers>

                <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />

            </Triggers>

        </asp:UpdatePanel>

        <asp:Button ID="btnStartProcess" Text="Start Background Process" runat="server" />

        <asp:Timer ID="Timer1" runat="server" Interval="1000">

        </asp:Timer>

    </div>

    </form>

</body>

</html>
 

WorkerThreadPage.aspx.vb:
 

Imports System.Threading
 

Partial Class WorkerThreadPage

    Inherits System.Web.UI.Page
 

    Private Event ThreadCompleted()

    Private Event ThreadProgress(ByVal threadProgress As Double)
 

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Not Page.IsPostBack Then

            Dim wThread As Thread = New Thread(AddressOf DoBackgroundWork)

            wThread.IsBackground = True

            Session("WorkerThread") = wThread

            AddHandler ThreadCompleted, AddressOf WorkerThreadCompleted

            AddHandler ThreadProgress, AddressOf WorkerThreadProgress

            Timer1.Enabled = False

            Session("IsComplete") = False

            Session("MaxRunningTime") = 100

            Session("ThreadProgress") = 0

        End If

        If Page.IsPostBack Then

            If (CType(Session("WorkerThread"), Thread).IsAlive = True) And (CType(Session("IsCompleted"), Boolean) = True) Then

                CType(Session("WorkerThread"), Thread).Abort()

            End If

        End If

    End Sub
 

    Protected Sub btnStartProcess_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnStartProcess.Click

        CType(Session("WorkerThread"), Thread).Start()

        processDiv.InnerText = "Processing Background Worker Thread, Status: 0%"

        Timer1.Enabled = True

    End Sub
 

    Private Sub DoBackgroundWork()

        Dim i As Integer = 0

        Do While i < CInt(Session("MaxRunningTime")) + 1

            If (i = CInt(Session("MaxRunningTime"))) Then

                RaiseEvent ThreadCompleted()

            End If

            RaiseEvent ThreadProgress(CDbl(100 * (i / CInt(Session("MaxRunningTime")))))

            Thread.Sleep(1000)

            i += 1

        Loop

        i = 0

    End Sub
 

    Private Sub WorkerThreadCompleted()

        Session("IsCompleted") = True

    End Sub
 

    Private Sub WorkerThreadProgress(ByVal threadProgress As Double)

        If threadProgress.ToString.Length > 5 Then

            Session("ThreadProgress") = threadProgress.ToString.Substring(0, 5)

        Else

            Session("ThreadProgress") = threadProgress.ToString

        End If

    End Sub
 

    Protected Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        processDiv.InnerText = "Processing Background Worker Thread, Status:" & Session("ThreadProgress").ToString & "%"

        If Session("IsCompleted") Then

            processDiv.InnerText = "Processing Background Worker Thread, Status: Finished!"

            Timer1.Enabled = False

        End If

    End Sub
 

End Class

Open in new window

0
 

Author Comment

by:scm0sml
ID: 22614373
is there not another way other than ajax?
0
 
LVL 18

Expert Comment

by:carlnorrbom
ID: 22614459
Hi,

Well, You could have asked that in your other question. There might be, however as far as I know the http.response object is not allowed in the background context where the worker thread is running, making it hard to update the ui. I figure ajax / client side checking is most efficient, otherwise setting up a service call (which would still need client side checking).

/Carl.
0
 

Author Comment

by:scm0sml
ID: 22614506
ok i have installed AJAXExtensionsToolbox.

Is that what is required for your work?

I have added a reference to it in the site but it doesnt like all your ajax components so i assume i have done something wr0ong or this isnt the correct thing to install?
0
 
LVL 18

Expert Comment

by:carlnorrbom
ID: 22614632
Hi,

It should only require Ajax extensions. If You drag an Ajax component from the toolbox onto the page it should register the ajax assembly with a certain prefix, i.e:

<%@ Register Assembly="AjaxExtensions" Namespace="AjaxExtensions" TagPrefix="Ajax" %>

You then need to make sure that the ajax components in the code are using that specific tag prefix. You should change:

<asp:ScriptManager... to <YourPrefix:ScriptManager...

<asp:UpdatePanel... to <YourPrefix:UpdatePanel...

<asp:AsyncPostBackTrigger... to <YourPrefix:AsyncPostBackTrigger...

<asp:Timer... to <YourPrefix:Timer...

Those are the only Ajax elements in the code.

/Carl.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:scm0sml
ID: 22614666
scrap that i hadnt made an changes to my webconfig file.

ok i am going to try again with your suggestion and see how i get on.
0
 

Author Comment

by:scm0sml
ID: 22614871
yeah ok i have got that working fine now.

so in the DoBackgroundWork() i call my sp correct?

and then in WorkerThreadCompleted() i would update labels etc

im not interested in the timer etc for my work correct?

and the labels to be changed will need to be inside my update panel?
0
 

Author Comment

by:scm0sml
ID: 22614994
also can i ask why u have put the workerthread in a session?
0
 

Author Comment

by:scm0sml
ID: 22615378
right ive got everything working nicely now using your example as a base so thanks for that.

my only concern is the use of the session.

like i say my stored proc is going to take some time to run and im worried about sessions timing out etc.

i could have a duration label on the page to help keep accessing certain sessions if that would help.

is it necassary though?

once i have this answer i think im just about there :)
0
 
LVL 18

Expert Comment

by:carlnorrbom
ID: 22615953
Hi again,

Well, the use of the Session variable is only because it's convinient. The nature of a webform and the continuos posting back to the server makes it a suitable solution. I guess you might be able to declare private variables on a class level but not sure whether they will be maintained cross postbacks or not.

If you keep the timer it will keep polling the server and maintain your session. If you don't want it to be that fluent you might might just change the interval to let's say 60000, then it will check and update your ui once a minute.

/Carl.
0
 

Author Closing Comment

by:scm0sml
ID: 31501969
got there in the end :)
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

A quick way to get a menu to work on our website, is using the Menu control and assign it to a web.sitemap using SiteMapDataSource. Example of web.sitemap file: (CODE) Sample code to add to the page menu: (CODE) Running the application, we wi…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now