Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

BarsRequest and cleanup

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    BarsRequest and cleanup

    I am using a BarsRequest object in the State.DataLoaded portion of OnStateChange to calculate some values from historical data.

    The code looks like this

    Code:
    var from = DateTime.Now.AddDays(-30);
    var barsRequest = new BarsRequest(Instrument, from, DateTime.Now);
    barsRequest.Request(
        (bars, errorCode, errorMessage) =>
        {
            // do some stuff here
            // barsRequest no longer needed so clean it up. Checking for null is pointless as we won't get in here if its not created
            barsRequest.Dispose();
        });
    barsRequest.Dispose(); // Not safe because Request may still be executing, if it executes asynchronously?
    I don't need the update event handler, nor do i need the BarsRequest after the Request has completed.

    I have a few questions.
    1. Is it safe to do this? Because Request hasn't finished and barsRequest object will be disposed this would be bad?
    2. Does Request execute asynchronously? I have not tested this but I guessed that it executes on some other thread, whenever the request has completed.

    #2
    Hello ntbone,

    In State.DataLoaded this would only be requested once, and this is a perfectly acceptable place to request some out of sync data.

    A BarsRequest is asynchronous and the callback is triggered once the request is complete. This where that data would be processed.

    Below are links to examples.

    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      In your first example, I don't see anywhere where the secondaryBarsRequest is disposed. It implements IDisposable so shouldn't Dispose be called both in RequestSeries() and State.Terminated?

      Back to my first question. from above is it safe to call Dispose from within the action passed in to barsRequest.Request()? I am trying to get rid of the barsRequest object as soon as I no longer need it. Since I only need historical data and not updated data I never connect to the event handler, and want to remove the object after I am done making the request and get back my data.

      Comment


        #4
        Hello ntbone,

        This is an old example all the way back from beta 8, and is on my radar for making a better example for.

        You are correct. There should be a removal of handlers and proper disposing of objects.

        The event assigned to Request should be removed and is being removed in the indicator's OnStateChange() when State is State.Terminated.

        Objects created may or may not need disposal depending on the object type and where it was created.
        As an example ints, bools, strings, don't need to be disposed and garbage collection from .NET will take care of it. Lists and array variables should be set to null so that they are marked for deletion on the next garbage collection pass for best efficiency. But if left, eventually garbage collection will clean it up if the owner was destroyed.
        Last edited by NinjaTrader_ChelseaB; 10-25-2020, 09:39 PM.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Yes. I am aware. I realized that BarsRequest implemented IDisposable so I added code to call dispose when I no longer need the object. In this case, I no longer need it once the initial request is complete, but figuring out when that happens so I can clean it up is unclear.

          Comment


            #6
            Hello ntbone,

            I wasn't aware BarsRequest implemented IDisposable, but in general I haven't needed to dispose of event handlers. I've needed to dispose of objects.

            Are you running into an error that is causing an issue with this?

            Or is this causing uncontrollable memory growth or some other issue?
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              BarsRequest is a class not an event, and I have created an object, not an event handler. In the documentation it specifically says to unsubscribe to the Update event handler if its used but I do not use it. My code creates a BarsRequest object, calls Request on it, and then wishes to dispose of the BarsRequest object when that request is finished. Since the request is handled asynchronously its unclear as to when the request is completed and thus when the object can be disposes. This forces me to keep the BarsRequest object alive until the terminated state when I could easily dispose of it much sooner.

              I am running into a resource related hang of NinjaTrader with the addition of this BarsRequest code but only after changing Instruments on the chart the indicator is on a number of times. The chart the indicator is on is linked to a MarketAnalyzer, and I scroll through the analyzer to look at charts for various instruments. After some time, the chart will hang, as well as the ControlCenter window and I will have to kill the process and restart. This only started happening with the introduction of the BarsRequest object being created.
              Last edited by ntbone; 10-25-2020, 10:22 PM.

              Comment


                #8
                Hello ntbone,

                The object can be disposed whenever you want. It doesn't have to be State.Terminate. You can dispose of it right after you use it if you really want.

                barsRequest.Dispose();
                barsRequest = null;

                Below is a link to the help guide on BarsRequest which shows how to call barsRequest.Dispose().

                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  Let me reiterate the problem.

                  BarsRequest.Request is a asynchronous. I am not using the Update event handler at all. If I were to do the following

                  Code:
                  var from = DateTime.Now.AddDays(-30);
                  var barsRequest = new BarsRequest(Instrument, from, DateTime.Now);
                  barsRequest.Request(
                      (bars, errorCode, errorMessage) =>
                      {
                          // do some stuff here
                  
                          // barsRequest no longer needed so clean it up.
                          barsRequest.Dispose();  // Calling this here is dangerous because barsRequest is still executing the Request function maybe? Its unclear.
                      });
                  barsRequest.Dispose(); // Not safe because Request may still be executing.  Request is asynchronous and thus the action inside it too.
                  So I cannot call barsRequest.Dispose() whenever I want. I need to call it after Request(...) call has finished executing its task, but there's no way to know that this has happened. At the moment the only safe place I know of to dispose of the barsRequest object is in the terminated handler.

                  Comment


                    #10
                    Hello ntbone,

                    If the BarsRequest object must be disposed immediately after the callback has completed, you could choose to use custom C# code to wait until the thread is done.

                    You could use a timer. You could use a new thread that sleeps. You could use ManualResetEvent.

                    Using lock would prevent other threads from modifying an object until the thread is complete.

                    Below is a publicly available link to a 3rd party educational site.
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      #11
                      Since I don't want the code sitting there waiting for the request to finish blocking the indicator from continuing, my choice is to clean up the barsRequest in terminate, or find some way to to alert the code that the request has finished so I can clean it up.

                      Comment


                        #12
                        Hello ntbone,

                        A timer could check once a second to see if the barsrequest callback has completed.

                        If the indicator is receiving data, you could wait until on the next bar close.

                        Otherwise you would have to block the indicator thread.
                        Chelsea B.NinjaTrader Customer Service

                        Comment

                        Latest Posts

                        Collapse

                        Topics Statistics Last Post
                        Started by rocketman7, Today, 02:12 AM
                        5 responses
                        23 views
                        0 likes
                        Last Post rocketman7  
                        Started by trilliantrader, 04-18-2024, 08:16 AM
                        7 responses
                        28 views
                        0 likes
                        Last Post NinjaTrader_BrandonH  
                        Started by samish18, 04-17-2024, 08:57 AM
                        17 responses
                        66 views
                        0 likes
                        Last Post NinjaTrader_BrandonH  
                        Started by briansaul, Today, 05:31 AM
                        1 response
                        15 views
                        0 likes
                        Last Post NinjaTrader_Jesse  
                        Started by PaulMohn, Today, 03:49 AM
                        1 response
                        12 views
                        0 likes
                        Last Post NinjaTrader_BrandonH  
                        Working...
                        X