Delegate.BeginInvoke Explaination

I just started to learning threading in Asp.net... I have few questions if someone could help me.

When doing Delegate.BeginInvoke, it takes a Thread from ThreadPool. so lets say if we do Delegate.BeginInvoke within a Loop (query 1000 request or send 1000 emails) is it going to borrow new thread for every new record or it will reuse the same one over and over again?

Delegate.BeginInvoke also has Delegate.endInvoke... is using EndInvoke Required? why do I have to use it?

Lets say by doing Delegate.BeginInvoke within the Delegate's provided Function, I want to update a LABEL  (like on which record we are on.. lbl1.text=myRecord), can we do this? simple example?

Also... is it good idea to use Delegate.BeginInvoke for busy web applications? or is it good only for Batch operations OR Intranets etc? Say I have 1000 users on my site and they all accessing a page which has Delegate.BeginInvoke, is it going to open 1000 threads and choke the server to crash?

Visual Stuido has 200 ThreadPools VS Deployed application which has 25 threadPools. is this true?

Thanks in advance
LVL 23
Saqib KhanSenior DeveloperAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

joriszwaenepoelCommented:
When you have 1000 calls to begininvoke, the first 25 (more or less) will be able to start immediatly on the trheadpool threads, then the others will start one by one when the previous calls have finished.

You must always call EndInvoke, because it is required to do some cleanup.  You can read more about that here:
http://msdn.microsoft.com/en-us/magazine/cc164036.aspx#S3

I think you will find the following article useful:
http://msdn.microsoft.com/en-us/magazine/cc163725.aspx
Saqib KhanSenior DeveloperAuthor Commented:
thank you for the links  joris...

but I was looking for some answers based upon personal experience. I'm in middle of developing an application.

have you used this before? and would you use it for a busy application as I mentioned above?
joriszwaenepoelCommented:
Hi,

Yes I used this before, not for thousands of calls to begininvoke, but for a few calls more or less at the same time.  It worked very well, but you have to be aware of the multithreading problems that might occur (race conditions, etc ...).  Also, I used it for WinForms apps, never voor web apps.

You should always call EndInvoke, because it allows you to find out if the call was successful, or if it ended with an exception, for example.  I found it best to use the callback method that is executed automatically when the call ends, then call endinvoke from there.  Of course in your situation it might be better to call EndInvoke and wait for the backgroudn task(s) to finish, or use some sort of polling mechanism to find out when the call has finished.  However, I always used the callback and I was very happy with the results.

Also, I would suggest that you only use this (multithreaded programmaing) when it is absolutely necessary, because of the added complexity.
Starting with Angular 5

Learn the essential features and functions of the popular JavaScript framework for building mobile, desktop and web applications.

Saqib KhanSenior DeveloperAuthor Commented:
makes sense.

my task is the following maybe you can help me.

I need to do Process on Customer Order

     GetOrder Details From Database
     Update Few Fields in Database
     Make few Insertions
     Send Email to Customer

so there are like 5 tasks i need to do for 1000+ Orders. I will have a Webserivce do all above steps within a Loop. that Loop with do BeginInvoke for the webservice to do the Tasks, I will Pass the CallBack Function as parameter and will do  EndInvoke within the CallBack Function.

This is an backend operation. and I will stick to CallBack Function trick as well.

any suggestions are welcome. I dont want my application to use all Threads within a Loop and choke down the server. I am new to this... this is why i am afraid:)
Saqib KhanSenior DeveloperAuthor Commented:
Can I do the following.

  Get a Thread from ThreadPool
  Wait for it to Finish all tasks
  When tasks are finished Close this Thread
  Then Reuse the Same/Different Thread

in other words, I want to make sure I am using one thread at a time within my LOOP.
joriszwaenepoelCommented:
Those 1000+ orders, are they coming more or less at the same time?  Or do they come one by one during the day?

If they come one by one, I wouldn't even bother to do this asynchronously, except maybe sending the email message (depending on how much feedback about the results you want to give to your user).

If they come in a batch (multiple orders at the same time), you can start all of them with BeginInvoke. If you need to give feedback to the user, then you have to wait until all of them have finished.

There is no need to go and monitor the thread usage yourself, let .NET handle that.  I'm sure they do this a lot better then we can.

Saqib KhanSenior DeveloperAuthor Commented:
they all Come as a batch.

so you saying BeginInvoke is just enough with EndInvoke? what if user wants to see on which order process is currently on and how many orders left behind? from Function i need to communicate with Control.

Thanks
joriszwaenepoelCommented:
You could start all of them with BeginInvoke, then count the number of callbacks (where you also call EndInvoke).  You can use this count to report the progress to the users.

However, keep in mind that that the callback is executed on the background thread, so you could have multiple callbacks running simultanously.  Watch out for race conditions on the counter variable, you will probably need to use a locking mechanism (for example SyncLock when using VB.NET or lock {} when using C#).

If you want to see which orders are currently processing (there will be more then 1 processing at the same time), you will need to create some mechanism yourself inside the asynchronous method.  FOr example, when starting to process each order, you could store the order-id in a "orders being processed" collection and remove it from that collection when the processing is finished.

Or you could keep it simpler and start only a limited number of delegates at once, assume these are processing immediatly, and then start the next one when a previous one has finished.  However, how will you determine the best number of concurrent asynchronous operations?  I don't know that.
Saqib KhanSenior DeveloperAuthor Commented:
What I am after could be explained via attached code.

So basicly Looper is the test Function in this example which will do some processing on ever order.

ImDone is the CallBack Function, which will do EndInvoke as well, and I can use it to update a label control within my aspx page as well.

what do you think about code and updating a label control? or maybe you have better idea?

By the way thanks for being patient with me so far:)
Imports System.Threading
Imports System.Runtime.Remoting.Messaging
Partial Class Delegates_Default2
    Inherits System.Web.UI.Page
    Private Delegate Sub iLoop(ByRef i As Int32)

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



        For i = 1 To 30


            Dim a As iLoop
            Dim ar As IAsyncResult
            a = New iLoop(AddressOf Looper)
            ar = a.BeginInvoke(i, New System.AsyncCallback(AddressOf imDone), Nothing)

        Next

        log.Text = "Hello World"


    End Sub


    Private Sub imDone(ByVal ar As IAsyncResult)

        Dim objResult As AsyncResult
        Dim mDel As iLoop
        Dim myI As Int32

        objResult = CType(ar, AsyncResult)

        mDel = objResult.AsyncDelegate

        mDel.EndInvoke(myI, ar)


       ' HERE I WANT TO UPDATE A LABEL CONTROL, LIKE CURRENLY ON WHICH ORDER I AM ON

        System.Diagnostics.Debug.WriteLine(myI & ":Callback Finished")

    End Sub

    Private Sub Looper(ByRef i As Int32)

        Dim availableThreads As Int32
        Dim b As Int16


        ThreadPool.GetAvailableThreads(availableThreads, b)



        System.Diagnostics.Debug.WriteLine(i)


        System.Diagnostics.Debug.WriteLine("This Value:" & i & ":avail Threads:" & Thread.CurrentThread.IsThreadPoolThread.ToString() & ":" & availableThreads & ":Current Thread" & Thread.CurrentThread.GetHashCode())

    End Sub

End Class

Open in new window

joriszwaenepoelCommented:
As I said, I haven't used this with ASP.NET, but I would be suprised if updating a label like this would have the desired effect.

If I remember correctly, then the result of an ASP.NET page is some HTML being sent back to the browser.  SO how could the value of a label change after is has been sent to the browser?

I'm not saying it's not possible, maybe with some kind of AJAX trick, or an AJAX Timer, but I think it will be a little more complicated then your example code here.  And unfortunately I won't be able to help with that.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Saqib KhanSenior DeveloperAuthor Commented:
Thank you...

Can you post one of the samples that you have done in past in win app's? if thats not too much of a trouble.

Thanks again
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
ASP.NET

From novice to tech pro — start learning today.