Avatar of krtarwood
krtarwood
 asked on

Errors which occur in worker thread not being raised in main application thread? (Using VB.Net)

Hello Experts!

I am sort of new to threading in ASP.Net so hopefully you can shed some light on what I am doing wrong here.

Essentially I have an application that runs a pretty lengthy process in a seperate sub. I want to thread the sub so I simply changed the call to the long running sub from Call buildDoc() to:

        Dim NewThread As New Thread(New ThreadStart(AddressOf buildDoc))

        NewThread.Priority = ThreadPriority.Lowest
        NewThread.Name = "CatalogBuild"
        NewThread.Start()

Seems like a good idea in theory as it does free up my UI to do other things, however it is obvious that the buildDoc subroutine is failing somewhere along the line (It programmatically instantiates a connection to a VPN and performs some transactions with our AS/400). The sub worked fine with the simple call but began failing after I threaded it. The problem is the process seems to die without throwing any of the exceptions that it used to so I can't tell what is going wrong.

I was told elsewhere that the only way to return exceptions thrown by threaded processes was to use delegates but I am unsure how that would help. Ideas? I have a top-level error handler setup in global.asax as such:

        Private Sub Global_Error(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Error
            Application("_ERROR") = Server.GetLastError()
            Dim ex As Exception = Server.GetLastError()

            If (Not ex Is Nothing) Then
                Dim innerException As Exception = ex
                ' Change to locale of error page
                Response.Redirect("~/error.aspx")
            End If

            ' Get rid of the progressbar on error
            Application("progress_" & Session.SessionID) = 100
            Application("complete_" & Session.SessionID) = True
        End Sub

Perhaps the above handler is not taking into account the specific type of exception that threads produce and hence isn't tripping when the error occurs?

I will post the contents of the buildDoc() sub if need-be but it is quite lengthy. You can view what it looks like by checking out the last comment on this previous post: https://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/Q_21933943.html

Any help would be thoroughly appeciated!

Thanks,
K
ASP.NET

Avatar of undefined
Last Comment
krtarwood

8/22/2022 - Mon
ASKER CERTIFIED SOLUTION
existenz2

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
krtarwood

ASKER
existenz2,

Thanks for the comment. I'd rather not use threading but right now I don't see any alternative as this process tends to take 7-8 minutes on the high end.

I was trying before to call the process as per normal and was using a progressbar class to display the progress in a javascript-produced popup window. The problem is I wanted a cancel button in the progressbar window to stop the procedure. It seems damn near impossible to do that from a separate page (and therefore completely separate class). Using Ajax seems like a little excessive to get a simple button working - I don't want to blow my timeline our of proportion for such an ansillary feature.

Perhaps I'm going about this the wrong way. I'm going to back up a couple steps and approach this from a fresh direction I think.

Anyone else have ideas?

Thanks,
K
nauman_ahmed

nauman_ahmed

Excerpt from above link:

In your delegate that launches the background thread, you can supply a
callback method that will be called when your thread has finished running.
In that callback method, you can reconstruct the original thread delegate
and then call its EndInvoke method within a Try...Catch block. If your
background thread threw an exception that it didn't handle, calling
EndInvoke will automatically rethrow that exception.

I've got some demonstration code for this lying around somewhere if you want
it. Alternatively, if you read VB, you can download the free online chapter
at the link below that demonstrates this mechanism.

HTH,

Mark
--
Author of "Comprehensive VB .NET Debugging"
http://www.apress.com/book/bookDisplay.html?bID=128

Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
existenz2

@nauman_ahmed:

He is making a ASP.NET application which automatically comes with statelessness. The url you posted is about Windows Applications and Threading. That are two kind of different games (Chess vs Soccer).
krtarwood

ASKER
Indeed. I couldn't find much documentation on implementing delegates w/ASP.Net.

Rgds,
K
krtarwood

ASKER
For those interested I am analyzing this article now:
http://msdn.microsoft.com/msdnmag/issues/05/10/WickedCode/

I am using .Net version 1.1.4322 currently as some of our other apps depend on it. It seems like version 2 supports much better asyncrhonous page handling. It may be time for an update..

Other solutions?

Thanks,
K
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
nauman_ahmed

existenz2:

The link I have posted was just for information :)

kratarwood:

Did you try catching exception in the delegate that is launching your thread? I just tried the following and the exception was caught in the delegate:

protected void Page_Load(object sender, EventArgs e)
    {
       

        try
        {
            ThreadStart ths = new ThreadStart(this.StartThread);
            Thread th = new Thread(ths);
            th.Start();
        }
        catch (Exception ex)
        {
            Response.Write(ex.ToString());
        }
       
    }

    private void StartThread()
    {
        try
        {
            throw new ArgumentException("Test");
        }
        catch (Exception ex)
        {
            Response.Write(ex.ToString());
        }
    }

--Nauman.
nauman_ahmed

I also came across the following article and it is using Thread Pooling to perform task that take long time.

Multithreading in ASP.NET
http://www.beansoftware.com/ASP.NET-Tutorials/Multithreading-Thread-Pool.aspx

--Nauman.
existenz2

This is an example of threading in .NET with an example: http://www.aspnl.com/aspnl/nl/artikelen/threading.asp

It's dutch though, but on the last line you got a download button with an explaining example :)
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
krtarwood

ASKER
Thanks guys,

Nauman - That article is a good primer and I read through it earlier today, the problem is that delegate sub isn't a complete piece of code and I don't get how to implement it. Further, after downloading the "complete example" it shows a partial class in the code-behind which makes no reference to the delegate sub. It doesn't really tell me how to do anything. Plus grabbing random processes from the thread pool is pretty much what I was trying to do above and it didn't return any exceptions.

existenz - I'll see if I can parse through that sample and get it working if my eyes stop bleeding from all the Dutch :)

Rgds,
K
krtarwood

ASKER
OK - Let me rephrase the goal - there is probably a better way to achieve...

You can check out Expedia or Orbitz for an example. They send you to a holding page while performing database lookups. The page is simple and shows a simple flash animation or animated gif to entertain you while the queries take place. I believe they're using simple meta refreshes to poll the server every once in a while to know when to redirect the client. Fine. This is basically what I want to do. I already have fully implemented progressbar code - I just don't know how to keep this process running in the background and have the app still responsive enough to send the client to a secondary page that can continually refresh to show progress.

By nature this doesn't seem possible with ASP.Net 1.1. As soon as you navigate the user away from the page which runs the lengthy procedure that procedure is killed... right?

By the same token, if I run the lengthy process on the same page as the waiting screen, wouldn't the waiting screen not even render until the process is complete?

Any ideas on a good way of accomplishing this?

Rgds,
K
SOLUTION
nauman_ahmed

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
krtarwood

ASKER
Ah! I suppose I should have known that :)

Thanks for the solution Nauman! 200 points to you for the win and 50 to existenz for steering me away from multithreading!

Rgds,
K
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.