• If this is your first visit, you will have to register before you can post. To view messages, please scroll below and select the forum that you would like to visits. Questions? Be sure to check out the Forum FAQ.

Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

NT8 D2D error

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

    NT8 D2D error

    Hello



    Should I use some lock object on OnRender() and in OnMarketDepth() methods to solve this issue? Or something else?

    #2
    Hello,

    Thank you for the question.

    This is likely not related to needing a lock, this is a D2D error or part of the rendering system.

    This could potentially be caused by code you are using in the case it causes the render to fail, or this could have come from some action.
    Can you tell me, does this occur while using specific syntax? if so could you provide a sample that shows the error for me to review?

    I look forward to being of further assistance.
    JesseNinjaTrader Customer Service

    Comment


      #3
      My typical draw code is like this. indicator var is my NT8 custom indicator instance.

      Code:
             public void Draw(ChartControl chartControl, ChartScale chartScale)
              {
                  float best_x = X + OUTER_MARGIN, trade_x;
                  float y0 = 0, y1 = 0;
      
                  // Best Ask
                  float h = Helper.GetRowYsHeight( chartScale, indicator.TickSize, lastAskPrice, ref y0, ref y1);
                  RectangleF bounds = new RectangleF(best_x, y0, BEST_BIDASK_WIDTH, h);
                  indicator.RenderTarget.DrawText(BestAskVolume.ToString(), tfVolume, bounds, indicator.AskBrush.ToDxBrush(indicator.RenderTarget));
      
                  // Offer traded volume
                  if (AskVolume > 0)
                  {
                      trade_x = best_x + BEST_BIDASK_WIDTH + INNER_MARGIN;
                      bounds = new RectangleF(trade_x, y0, TRADE_WIDTH, h);
                      indicator.RenderTarget.FillRectangle(bounds, indicator.AskBrush.ToDxBrush(indicator.RenderTarget));
                      indicator.RenderTarget.DrawText(AskVolume.ToString(), tfVolume, bounds, indicator.TapeSnapshotAskVolumeBrush.ToDxBrush(indicator.RenderTarget));
                  }
      
                  // Best Bid
                  h = Helper.GetRowYsHeight(chartScale, indicator.TickSize, lastBidPrice, ref y0, ref y1);
                  bounds = new RectangleF(best_x, y0, BEST_BIDASK_WIDTH, h);
                  indicator.RenderTarget.DrawText(BestBidVolume.ToString(), tfVolume, bounds, indicator.BidBrush.ToDxBrush(indicator.RenderTarget));
      
                  // Bid traded volume
                  if (BidVolume > 0)
                  {
                      trade_x = best_x + BEST_BIDASK_WIDTH + INNER_MARGIN;
                      bounds = new RectangleF(trade_x, y0, TRADE_WIDTH, h);
                      indicator.RenderTarget.FillRectangle(bounds, indicator.BidBrush.ToDxBrush(indicator.RenderTarget));
                      indicator.RenderTarget.DrawText(BidVolume.ToString(), tfVolume, bounds, indicator.TapeSnapshotBidVolumeBrush.ToDxBrush(indicator.RenderTarget));
                  }
              }

      Comment


        #4
        Hello,

        Have you determined this code specifically controls the error? What i mean is that if you comment out this code would the error still occur or does this specifically control it?

        I am unable to compile the sample provided to test if this does cause an error or not, in the case this is the specific syntax controlling the error I would like to ask for a sample I could compile and test.

        I look forward to being of further assistance.
        JesseNinjaTrader Customer Service

        Comment


          #5
          It makes no sense because of error occurred only sometimes, 1 from 10 run I think. And I have no idea what class from 5-6 plotted classes makes issue.

          As I have learned from this https://msdn.microsoft.com/en-us/lib...v=vs.110).aspx
          exeption might occurred after thread tries to get write lock for some resource.
          E.g. changing TextFormatLayout object instance after it was created and shared with others threads. Am I right?

          Btw, can OnRender() method be called from different threads by NT core, waiting for timeout and throwing lock exeption on time expired?

          What does this code? Should I dispose DxBrush after using or it will be disposed by D2D library? If not, next time I call ToDxBrush() will it look for brush in D2D global or app cache? Now it's unclear for me.

          Code:
          Brush.ToDxBrush(RenderTarget)
          In .Net Framework 3.5 and NT7 application have to dispose all unmanaged resources like pens and brushes. But what to do with SharpDX resources?
          Last edited by ren37; 06-09-2016, 04:22 PM.

          Comment


            #6
            Hello,

            Thank you for the reply.

            I would be unsure if what you are experiencing would be related to the MSDN article, the sharpDX render errors can come from many items in the platform as the platform uses SharpDX for rending most types of items.

            Again it would be hard to say depending on what has been provided if that is related or not, have you noted if you do not use the custom code, do you receive the same error when completing any specific actions?

            If this is only being caused while using the custom code, there is a good likelihood some portion of that logic is the cause, otherwise if this can be reproduced in other ways I would like to know the steps used.

            Regarding the OnRender being accessed from multiple threads, this is a question I could not answer with accuracy as I am unaware of the total process going on internally surrounding OnRender. Generally speaking the NinjaScript item you are using would only be in one thread and all items it uses would be in the associated thread.

            Regarding disposing resources, in general you will need to dispose resources you create that you no longer need. This is not specific to NinjaTrader but specific to C# in general. In the case of brushes, you could dispose of a brush by calling its Dispose method.

            In most cases it is best to do creation and disposal of objects in the OnRenderTargetChanged override. We have an example that applies to this question here: http://ninjatrader.com/support/helpG...rTargetChanged

            I look forward to being of further assistance.
            JesseNinjaTrader Customer Service

            Comment


              #7
              Hello

              I have never seen this D2D error on NT8 before, but I'm using NT8 less than one month and mainly for indicators developing. Perhaps it related with with Level 2 drawing. I'll try to isolate the error.

              Ty for graphical resources management hint.

              Comment


                #8
                I am glad that I am not alone in getting this D2D error. I get this error from the following actions using a custom indicator.

                1. The custom indicator draws 4 rows of rectangles at the bottom of the price chart, using RenderTarget.FillRectangle() and SharpDX.Direct2D1.LinearGradientBrush, which is created and disposed for each rectangle. This is necessary as the color of each rectangle is different.

                2. To avoid memory leak, the code is wrapped with using(SharpDX.Direct2D1.LinearGradientBrush LinGradBrush = GetLinGradBrush(rectf, Color0, 0f, Color1, fPos1, Color2, 1f)) {} and both the LinearGradientBrush and GradientStopCollection are disposed() accordingly.

                3. Under normal condition, using a chart about 10 tabs, there is no noticeable error message.

                4. When the Kinetick connection is activated, this error would start to happen, although not too often. However, if the Kinetick connection is activated and de-activated many times, this error would occur more often, causing NinjaTrader to freeze. The only way to terminate is using the Task Manager.

                5. When the RenderTarget.FillRectangle() is replaced with a SharpDX geometry code, the D2D error would be less frequent but it did not solve the problem.

                6. The next thing to try is to reuse the LinearGradientBrush, instead of creating and disposing for each rectangle. If any one could provide coding to reuse the LinearGradientBrush, or to resolve this D2D error, it would be greatly appreciated.

                Comment


                  #9
                  kkc2015,

                  In my custom indicator I have never seen this D2D error after reusing DX brushes.
                  But some dynamicaly calculated DX brushes still created and disposed inside OnRender() call.

                  PHP Code:
                          [Browsable(false)] [XmlIgnore] public SharpDX.Direct2D1.Brush AskBrushDx get; protected set; }
                  ...

                          public 
                  override void OnRenderTargetChanged()
                          {
                              
                  DisposeUnmanagedGraphics();

                              
                  AskBrushDx AskBrush.ToDxBrush(RenderTarget);
                              ...
                          }

                          private 
                  void DisposeUnmanagedGraphics()
                          {
                              if (
                  AskBrushDx != nullAskBrushDx.Dispose();
                              ...
                          }

                          protected 
                  override void OnStateChange()
                          {
                                 ...            
                              else if (
                  State == State.Terminated)
                              {
                                  
                  DisposeUnmanagedGraphics();
                                   ...
                               }
                          } 

                  Comment


                    #10
                    I also had exceptions when re-using global brushes.
                    The problem was solved using local variables with using blocks.


                    Code:
                    protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
                    {
                       ...
                       using (SharpDX.Direct2D1.Brush myBrush = new SolidColorBrush( Colors.Blue ).ToDxBrush( RenderTarget ))
                       {
                          // painting
                       }
                    Last edited by cls71; 06-17-2016, 02:21 AM.

                    Comment


                      #11
                      Sorry, I think I should modify DisposeUnmanagedGraphics()

                      PHP Code:
                              private void DisposeUnmanagedGraphics() 
                              { 
                                  if (
                      AskBrushDx != null) { AskBrushDx.Dispose(); AskBrushDx null; }
                                  ... 
                              } 
                      Last edited by ren37; 06-17-2016, 12:08 PM.

                      Comment


                        #12
                        Originally posted by cls71 View Post
                        I also had exceptions when re-using global brushes.
                        The problem was solved using local variables with using blocks.


                        Code:
                        protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
                        {
                           ...
                           using (SharpDX.Direct2D1.Brush myBrush = new SolidColorBrush( Colors.Blue ).ToDxBrush( RenderTarget ))
                           {
                              // painting
                           }
                        In my mind better to store brushes and recreate them in OnRenderTargetChanged() as NT support have advised.

                        Comment


                          #13
                          Thank you for the suggestions, ren37 and cls71.

                          Except for the LinearGradientBrush, all DX brushes are cloned and frozen inside (State == State.Historical) and disposed of inside OnRenderTargetChanged(), as per sample reuseablebrushes.zip provided by NinjaTrader.

                          As commented on my previous item 2, to avoid memory leak, the LinearGradientBrush was wrapped with the "using statement block" because I do not know how to reuse it. I was hoping that if the LinearGradientBrush were to be reused, it may solve the problem. Do you have any ideas how this can be achieved?

                          By the way, if many lines were drawn using the following codes, the same D2D error would occur occasionally with multi-tab chart and activation cycling of the Kineticks connection.
                          SharpDX.Direct2D1.StrokeStyle strokeStyle = new Stroke(Brushes.Gray, DashStyleHelper.DashDotDot, 1f).StrokeStyle;
                          RenderTarget.DrawLine(P1.ToVector2(), P2.ToVector2(), upLineBrushDx, 1f, strokeStyle);
                          The error would be resolved if strokeStyle is not passed to the DrawLine() function. Any help on this would also be appreciated.

                          Comment


                            #14
                            Originally posted by kkc2015 View Post
                            Thank you for the suggestions, ren37 and cls71.

                            Except for the LinearGradientBrush, all DX brushes are cloned and frozen inside (State == State.Historical) and disposed of inside OnRenderTargetChanged(), as per sample reuseablebrushes.zip provided by NinjaTrader.

                            As commented on my previous item 2, to avoid memory leak, the LinearGradientBrush was wrapped with the "using statement block" because I do not know how to reuse it. I was hoping that if the LinearGradientBrush were to be reused, it may solve the problem. Do you have any ideas how this can be achieved?

                            By the way, if many lines were drawn using the following codes, the same D2D error would occur occasionally with multi-tab chart and activation cycling of the Kineticks connection.
                            SharpDX.Direct2D1.StrokeStyle strokeStyle = new Stroke(Brushes.Gray, DashStyleHelper.DashDotDot, 1f).StrokeStyle;
                            RenderTarget.DrawLine(P1.ToVector2(), P2.ToVector2(), upLineBrushDx, 1f, strokeStyle);
                            The error would be resolved if strokeStyle is not passed to the DrawLine() function. Any help on this would also be appreciated.

                            Have you seen my example about reusing brushes?
                            http://ninjatrader.com/support/forum...83&postcount=9

                            As what about your 2nd question see code below.

                            PHP Code:

                                    
                            [Display(Name "Line"Order 2GroupName "8. Price line")]
                                    public 
                            Stroke PriceLineStroke
                                    
                            getset; }

                                    private 
                            SharpDX.Direct2D1.Brush PriceLineBrushDx;

                                    public 
                            override void OnRenderTargetChanged()
                                    {
                                        if (
                            PriceLineBrushDx != null) { PriceLineBrushDx.Dispose(); PriceLineBrushDx null; }
                                        
                            PriceLineBrushDx PriceLineStroke.Brush.ToDxBrush(RenderTarget);
                                     }

                                    protected 
                            override void OnRender(ChartControl chartControlChartScale chartScale)
                                    {
                                        if (
                            ChartBars != null)
                                        {

                                                
                            RenderTarget.DrawLine(new Vector2(xy0 2), new Vector2(chartControl.CanvasRighty0 2),
                                                    
                            PriceLineBrushDxPriceLineStroke.WidthPriceLineStroke.StrokeStyle);
                                         ...
                                         }
                                     } 

                            Comment


                              #15
                              Thank you all for your help. Much appreciated.

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by RandanAL, 09-21-2019, 09:05 AM
                              1 response
                              10 views
                              0 likes
                              Last Post NinjaTrader_ChrisSch  
                              Started by afoschini, Today, 02:57 AM
                              0 responses
                              1 view
                              0 likes
                              Last Post afoschini  
                              Started by Newtrader101, Yesterday, 06:31 PM
                              1 response
                              9 views
                              0 likes
                              Last Post NinjaTrader_EricB  
                              Started by Tyler7498, Yesterday, 07:34 PM
                              0 responses
                              4 views
                              0 likes
                              Last Post Tyler7498  
                              Started by Woomera, Yesterday, 07:24 PM
                              2 responses
                              10 views
                              0 likes
                              Last Post Woomera
                              by Woomera
                               
                              Working...
                              X