Console app takes a long time to exit after finishing work

Hangman

I have a console app that queries a database and then posts some records to a REST API in a loop (the api does not support batch posting, so I have to loop through each record and post individually, if its relevant). The database access is fast and no issue and so is the api post loop according to the timer I've put in place, however the app itself takes a long time to exit after the work is done.

This started happening after I introduced Parallel.Foreach to speed up the posting. Before using a non-parallel loop, posting 1000 records took on average ~10mins, but the app would return and exit immediately when it was done (as expected). With the parallel loop in place, this, according to the Stopwatch timer I'm using, is reduced to an average of ~44secs, however the app doesn't exit until around 2 minutes have passed - ~1min15sec after all work has completed.

The app isn't doing anything 'extra'. It enters main, main calls a method to retrieve some records from a database (1-2 secs), forwards 1000 of those records to another method that loops through them and posts each to the api, then exits. Except, it doesn't exit immediately in this case, for some reason.

I put a stopwatch timer in main immediately before the call to the posting method and log the time immediately after the method returns, and the timer aligns with the timer inside the method, averaging ~46 seconds. So the delay is happening after the posting method has returned but before the main function exits, but there is nothing defined for it to do at this point. Debugging didn't show anything out of the ordinary. Is this a de-allocation issue related to all the objects spawned by the parallel loop that are 'hanging around'?

This happens regardless of whether I am running with a debugger attached or executing the binary directly when built for release (so not a detaching delay issue). I've looked at other SO questions like this but their approaches have not made a difference. Any input would be appreciated.

Code of the posting function:

public ProcessingState PostClockingRecordBatchParallel(List<ClockingEvent> batch, int tokenExpiryTolerance)
{
    log.Info($"Attempting to post batch of {batch.Count.ToString()} clocking records to API with an auth token expiry tolerance of {tokenExpiryTolerance} seconds");
    try
    {
        ProcessingState state = new ProcessingState() { PendingRecords = batch };
        List<ClockingEvent> successfulRecords = new List<ClockingEvent>();
        Stopwatch timer = new Stopwatch();

        ServicePointManager.UseNagleAlgorithm = false; //Performance optimization related to RestSharp lib
        authToken = Authenticate();

        timer.Start();
        Parallel.ForEach(state.PendingRecords, pr =>
        {
             successfulRecords.Add(PostClockingRecord(pr, tokenExpiryTolerance));
        });
        //Prior non-parallel version
        //state.PendingRecords.ForEach(pr => 
        //{
        //    successfulRecords.Add(PostClockingRecord(pr, tokenExpiryTolerance));
        //});


        state.PendingRecords        = state.PendingRecords.Except(successfulRecords).ToList();
        state.LastSuccessfulRecord  = successfulRecords.OrderBy(r => r.EventID).Last().EventID;

         log.Info($"PostClockingRecordBatchParallel - Time elapsed: {new TimeSpan(timer.ElapsedTicks).ToString()}");
         return state;
    }
    catch (Exception ex)
    {
            log.Fatal($"Failed to post records to API (exception encountered: {ex}).");
         throw;
    }
}
user3956566

Yes it would be freeing up the memory. Your thread will be using up memory and you can limit this by using ParallelOptions.MaxDegreeOfParallelism Property, which will then slow down the query, of course, and you need to manage the memory deallocation - if you want to reduce the time taken to exit the application.

You can dispose of your tasks, if scalability is an issue and you use up too much memory, or wish to clean up resources as you go. As the Parallel class extends the Task class.

Although, calling the garbage collector may be a more foolproof design for you.

How can I free-up memory used by a Parallel.Task?

To reduce the garbage collection at the end of the run, you can implement your own garbage collection, as shown in this answer

Action allCollect = () =>
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
        };

Where you can periodically manually call for garbage collection.

Also helpful:
Possible memoryleak in ConcurrentBag?

This answer gives examples of how to use MaxDegreeOfParallelism

ParallelOptions.MaximumDegreeOfParallelism = 1: use one full CPU (which will be a percentage of your OS CPU)

Managing this is important if you wish to scale your application, so as to avoid memory leaks and OutOfMemoryException.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Codeblocks takes long time to execute after compiling

WKWebView in iOS app takes a long time to load

C++ large deque - program takes very long time to exit?

Environment.Exit takes long time to close the application

exit console app after completing process

Creating FCM Topics takes a long time to show in console

Aggregate takes a long time

Firestore takes a long time to end execution after executing

This programs takes a long time to close after the 'return;' on main()

iOS takes long time to update view after HTTP request?

Login screen takes a long time to open after suspend

Android Studio Takes too long time to run the app on real device

How long would the system takes to kill an app after UIApplicationWillTerminateNotification is sent?

How long does it take for the app to time out and exit the conversation

MCSession takes a long time to dealloc

switch to root takes long time

tensorflow session() takes long time

Initializing font takes a long time

npm search takes a long time

exec php takes long time

UiViewController takes a long time to display

Ubuntu takes long time to boot

Regex takes a long time to complete

Xubuntu takes long time to boot

kernel takes long load time

My angular 2 app takes a long time to load for first time users, I need help to speed it up

google app engine deploy a custom vm app takes a long time to deploy

My map application doesn't work after a long period of time

Visual Studio 2015 takes a long time (10 - 15 minutes) to reload projects after a "Get Latest" from TFS

TOP Ranking

  1. 1

    Failed to listen on localhost:8000 (reason: Cannot assign requested address)

  2. 2

    Loopback Error: connect ECONNREFUSED 127.0.0.1:3306 (MAMP)

  3. 3

    How to import an asset in swift using Bundle.main.path() in a react-native native module

  4. 4

    pump.io port in URL

  5. 5

    Compiler error CS0246 (type or namespace not found) on using Ninject in ASP.NET vNext

  6. 6

    BigQuery - concatenate ignoring NULL

  7. 7

    ngClass error (Can't bind ngClass since it isn't a known property of div) in Angular 11.0.3

  8. 8

    ggplotly no applicable method for 'plotly_build' applied to an object of class "NULL" if statements

  9. 9

    Spring Boot JPA PostgreSQL Web App - Internal Authentication Error

  10. 10

    How to remove the extra space from right in a webview?

  11. 11

    java.lang.NullPointerException: Cannot read the array length because "<local3>" is null

  12. 12

    Jquery different data trapped from direct mousedown event and simulation via $(this).trigger('mousedown');

  13. 13

    flutter: dropdown item programmatically unselect problem

  14. 14

    How to use merge windows unallocated space into Ubuntu using GParted?

  15. 15

    Change dd-mm-yyyy date format of dataframe date column to yyyy-mm-dd

  16. 16

    Nuget add packages gives access denied errors

  17. 17

    Svchost high CPU from Microsoft.BingWeather app errors

  18. 18

    Can't pre-populate phone number and message body in SMS link on iPhones when SMS app is not running in the background

  19. 19

    12.04.3--- Dconf Editor won't show com>canonical>unity option

  20. 20

    Any way to remove trailing whitespace *FOR EDITED* lines in Eclipse [for Java]?

  21. 21

    maven-jaxb2-plugin cannot generate classes due to two declarations cause a collision in ObjectFactory class

HotTag

Archive