Solved

using a thread to call my function

Posted on 2008-10-01
11
1,191 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
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 

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
 

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

Comprehensive Backup Solutions for Microsoft

Acronis protects the complete Microsoft technology stack: Windows Server, Windows PC, laptop and Surface data; Microsoft business applications; Microsoft Hyper-V; Azure VMs; Microsoft Windows Server 2016; Microsoft Exchange 2016 and SQL Server 2016.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

777 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