Why does ThreadPool.GetAvailableThreads not work?

I have a method for processing strings from a datatable using multiple threads, it queues all work items and then checks that they were all processed, and not leaving this method until they are.

It seems to work fine in development, but when I paste it into the server (64-bit) for testing, it will not wait for the end of the method. It does not seem to make Thread.Sleep () calls, as the method is immediately deleted.

It will continue to process datarows after exiting the method, but that is not what I want.

Any ideas? Thanks

Public Sub ProcessAll(ByVal collection As DataTable, ByVal processDelegate As WaitCallback) Dim workItem As DataRow Dim availableThreads As Integer Dim completionPortThreads As Integer ThreadPool.SetMaxThreads(MAX_THREADS, MAX_THREADS) ' loop round processing each pending record adding them to the Thread Queue For Each workItem In collection.Rows ThreadPool.QueueUserWorkItem(processDelegate, workItem) Next ' The ThreadPool is a collection of background threads, thus we need to do something to stop the main thread from moving on Do Thread.Sleep(1000) ThreadPool.GetAvailableThreads(availableThreads, completionPortThreads) ' in the case that all threads are free (how we check all are complete) wait a few seconds just to make sure If availableThreads = MAX_THREADS Then Thread.Sleep(5000) ThreadPool.GetAvailableThreads(availableThreads, completionPortThreads) End If Loop While availableThreads < MAX_THREADS End Sub 
+4
source share
1 answer

You should not do this in such a way as to wait for all lines to finish.

Instead, you should use the notification method, which from your processing code will tell a piece of code that "hey, I just finished the line."

This way you can more easily track how many lines have been processed.

How will I do it:

  • Add an Int32 value initialized to 0 that keeps track of how many have been processed
  • Use Interlocked.Increment to increase this in your deletet
  • Define an event object in your delegate after incrementing the counter
  • In your main method, I will wait until the event is set, and then check the counter. If it is not tall, go back and wait again.

T. something like:

 private volatile Int32 _Processed = 0; private AutoResetEvent _RowProcessedEvent = new AutoResetEvent(false); ... in your delegate: Interlocked.Increment(ref _Processed); _RowProcessedEvent.Set(); ... in your main method: while (_Processed < collection.Rows.Count) { _RowProcessedEvent.WaitOne(Timeout.Infinite); } 

Remember to close the event object when you are done with it.

+5
source

Source: https://habr.com/ru/post/1300386/


All Articles