using a thread to call my function

Posted on 2008-10-01
Medium Priority
Last Modified: 2011-09-20

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()

            'Once the thread has finished we need to display this to the user and amend the user interface accordingly.
        Catch ex As Exception
        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
            'set execution running in its own thread
            uploadThread = New Thread(AddressOf ExecuteUpload)
        Catch ex As Exception
        End Try

Open in new window

Question by:scm0sml
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
LVL 18

Accepted Solution

carlnorrbom earned 2000 total points
ID: 22614352

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

<%@ 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>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    <div style="border: Solid 1px Gray;padding: 5px 5px 5px 5px;margin-top: 50px;">
        <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="False">
                <div id="processDiv" runat="server">
                <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
        <asp:Button ID="btnStartProcess" Text="Start Background Process" runat="server" />
        <asp:Timer ID="Timer1" runat="server" Interval="1000">
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")))))
            i += 1
        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)
            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


Author Comment

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

Expert Comment

ID: 22614459

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).


Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.


Author Comment

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?
LVL 18

Expert Comment

ID: 22614632

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.


Author Comment

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.

Author Comment

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?

Author Comment

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

Author Comment

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 :)
LVL 18

Expert Comment

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.


Author Closing Comment

ID: 31501969
got there in the end :)

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Suggested Courses

752 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