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

Can we use "cloned" object instead of `lock`-ing the execution?

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

    Can we use "cloned" object instead of `lock`-ing the execution?

    In the example of: https://ninjatrader.com/support/help...vel_ii_dat.htm
    In sample indicator, we see "OnMarketDepth" example usage. However, there is used :

    lock (e.Instrument.SyncMarketDepth)

    however, per my doubts, that locks and sometimes delays WHOLE NINJATRADER (i spoted that in the DOM for specific symbol, was not being updated when I have applied a complex indicator for that symbol's chart).

    So, my question is : is not it better to "clone/copy" that object and continue further code with cloned object, instead of the `e.Instrument.MarketDepth` ?

    For example, using Cloning ,so, we didn't used the `lock` at all?
    Last edited by ttodua; 06-02-2020, 02:05 PM.

    #2
    Hello ttodua,

    Thanks for your question.

    Copying the object can be more resource intensive than simply locking the collection so other threads cannot access it while it is locked. We would also likely want to consider locking when the copy is made anyway, since the the collection can still be modified from other threads if it is not locked.

    A StackOverflow article which further discusses locking vs. copying can be found below if you would like to read more about locks and cloning and what other perspective developers have shared with their projects. (This resource is publicly available.)

    I have a DataTable that can contains a large number of DataRows; this DataTable can be accessed from several threads. Some threads can also change values into some rows. Actually there are some sea...


    We look forward to assisting.
    JimNinjaTrader Customer Service

    Comment


      #3
      Jim, thanks for the informative topic, it was quite good.
      my question :
      I've concludes, that there are 3 possible ways to do locking.


      (approach 1)

      use `lock` for complete area (like documented in the referenced link's example indicator)


      (approach 2)

      use `lock` only initially for accessing `e` object once and other global scope variables too

      Code:
      Dictionary<...> myDt ;
      
      protected override void OnMarketDepth(MarketDepthEventArgs e)
      {
          var price=0;
          var volume= 0;
          lock(...)
          {
              price = e.Price;
              volume = e.Volume;
              // Also, here should be all uses of global-scope variables, like : myD
          }  
          .............
          .............
          .............
          .............
          ....... other calculations here, which doesn't access neither `e` not `myD` like global-scope variables, to avoid in-flight changes because of  parallel writing, caused by `outside of lock` operation.......
          .............
          .............
          .............
          .............
          .............


      (approach 3)

      ReaderWriterLockSlim seems the most promising! I have made the following example. Is not this a better approach, to allow multiple(parallel) reads? so why NT doesn't use that in documentation?:

      Code:
      public static Dictionary<string,System.Threading.ReaderWriterLockSlim> tableLock_OnMarketDepth = new Dictionary<string, System.Threading.ReaderWriterLockSlim>();
      
      protected void lockSymbol(string instrumentName, bool Lock_Unlock)
      {
          if (Lock_Unlock) tableLock_OnMarketDepth[instrumentName].EnterReadLock();
          else tableLock_OnMarketDepth[instrumentName].ExitReadLock();
      }
      
      
      
      protected override void OnMarketDepth(MarketDepthEventArgs e)
      {
          try
          {
              //lock (e.Instrument.SyncMarketDepth) <--   removed
              lockSymbol(e.Instrument.FullName, true);
              {
                    .............
                    .............
                    .............
                    .............
                    .............
              }
          }
          catch (Exception ex)
          {
              ...
          }
          finally
          {
              lockSymbol(e.Instrument.FullName,false);
          }
      }
      because If i correctly understood about ReaderWriterLock, while there happens "read" processes (even multiple), write wouldnt happen. Is that correct?
      Last edited by ttodua; 06-03-2020, 03:59 AM.

      Comment

      Latest Posts

      Collapse

      Topics Statistics Last Post
      Started by algospoke, Yesterday, 06:40 PM
      2 responses
      19 views
      0 likes
      Last Post algospoke  
      Started by ghoul, Today, 06:02 PM
      3 responses
      14 views
      0 likes
      Last Post NinjaTrader_Manfred  
      Started by jeronymite, 04-12-2024, 04:26 PM
      3 responses
      45 views
      0 likes
      Last Post jeronymite  
      Started by Barry Milan, Yesterday, 10:35 PM
      7 responses
      20 views
      0 likes
      Last Post NinjaTrader_Manfred  
      Started by AttiM, 02-14-2024, 05:20 PM
      10 responses
      180 views
      0 likes
      Last Post jeronymite  
      Working...
      X