2009-11-12 60 views
1

我正在測試我最近完成的DX滾動橫幅。問題是它消耗了大量的內存。C#怎麼了font.DrawText

要滾動的字符串是使用從源字符串(rss提要)創建並存儲在數組中的字符數組及其大小(使用DX度量字符串)創建的。 rss feed在這種情況下大約有500個字符。

要創建滾動字符串,我只需在顯示面板上添加/刪除字符作爲進入/離開視圖(使用面板寬度&字符大小以確定添加/刪除字符串中的字符的時間)。它工作得很好,但使用200M的內存。字符串永遠不會超過80個字符長(如果超過80個字符,我會通過使用警報來確保這一點)。字符串中的字符數量當然取決於字體的大小。

如果我註釋掉DrawText命令,應用程序會使用很少的內存(證明它不是代碼的其他部分)。如果我只是滾動整個字符串(500個字符),則使用的內存只有32M。但是,我現在正在使用大量的Proc滾動這麼大的字符串。我注意到當你繪製一個靜態(不滾動)的大字符串,然後跟着它,例如單個字符字符串,DrawText不釋放用於繪製大字符串的內存。我正在使用theString.Remove & theString.Insert創建要滾動的字符串。內存似乎隨着每個字符的增加/減少而上升,並且一旦整個RSS提要字符串被滾動,內存使用保持靜態 - 在200M處 - 從此開始。

發生了什麼事?非常感謝任何幫助......這讓我瘋狂!我可以將feed分解爲字符串,但更有意義的是按字符進行。

private void sync() 
    { 
     if (device.RasterStatus.ScanLine) 
     { 
      UpdateDisp();    

      if (ArStringSegments.Count != 0) 
      { 
       for (int i = 0; i != Speed; i++) 
       { 
        # region Add a character to the displayed string      

        if (FirstCharLength == 0 && AddChrIndex != ArStringSegments.Count) 
        { 
         StringProps StringProps = (StringProps)ArStringSegments[AddChrIndex]; 

         if (ScrollDirection == Direction.ToLeft) 
         {        
          theString = theString.Insert(theString.Length, StringProps.String); 

         } 
         AddChrIndex++; 
        } 
        # endregion Add a character to the string 

        # region remove a character from the string as it goes beyond the veiwable area 

        if (RemoveChrIndex != ArStringSegments.Count) 
        { 
         if (ScrollDirection == Direction.ToLeft) 
         {        
          if(ScrollInc == 0 - LargestChar) 
          { 
          StringProps RemoveString = (StringProps)ArStringSegments[RemoveChrIndex]; 
          theString = theString.Remove(0, 1); 
          ScrollInc += RemoveString.Size1; 
          RemoveChrIndex++; 

          } 
         } 
        } 
        # endregion remove a character from the string as it goes beyond the veiwable area 

        # region Increment/decrement position 

        if (ScrollDirection == Direction.ToLeft) 
        { 
         ScrollInc--; 
         FirstCharLength--; 
        } 
        # endregion Increment/decrement position       

        # region Entire string has gone out of viewable area, scroll out by an amount and then start again. 

        if ((ScrollInc == 0 - (ScrollOutLength + LargestChar) && ScrollDirection == Direction.ToLeft) || 
          (ScrollInc == PanWidth + (ScrollOutLength + LargestChar) && ScrollDirection == Direction.ToRight)) 
        { 
         theString = ""; 
         AddChrIndex = 0; 
         RemoveChrIndex = 0; 
         FirstCharLength = 0; 


         if (ScrollDirection == Direction.ToLeft) 
         { 
          ScrollInc = this.PanWidth;         
         } 
         else 
         { 
          ScrollInc = 0; 
          RightBoundary = 0; 
         } 
        } 
        # endregion entire string has gone out of viewable area, scroll out by an amount and then start again. 
       } 
      } 

     } 
     ScanCount = device.RasterStatus.ScanLine; 
    } 


private void UpdateDisp() 
    { 
     try 
     { 
      if (device.CheckCooperativeLevel(out DeviceStatus)) 
      {     

       if (UpdateDisplayEnabled == true) 
       { 
        device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0); 
        device.BeginScene(); 

        // background image Texture      
        BackSprite = new Sprite(device); 
        BackSprite.Begin(SpriteFlags.AlphaBlend); 
        BackSprite.Draw2D(PanelTexture, new Point(0, 0), 0.0F, new Point(0, 0), Color.White); 
        BackSprite.End(); 
        BackSprite.Dispose(); 

        // draw the text            
         Draw2DText(FeedText[i], ScrollInc, 0, FontColor); 
        font.DrawText(null, theString, new Rectangle(ScrollInc, 0, 

        device.EndScene(); 
        if (device.CheckCooperativeLevel(out DeviceStatus)) device.Present((IntPtr)DxRenderPanel); 

       } 
      } 
     } 
+0

這發送更新每次掃描行數達到0 – user183185 2009-11-12 18:24:01

回答

3

我們看不到你的代碼,所以我可以給你的只是猜想。考慮到這一點:

.Net使用垃圾收集來管理內存。爲了提高效率,垃圾收集器可能會決定它不需要釋放內存,直到有來自某個地方的壓力才能釋放內存。如果你的機器有幾千兆字節的RAM,比沒有壓力釋放它,這可能會很好。

這就是說,有些事情你可能做錯了,以防止垃圾收集器釋放內存,否則它可能非常樂意返回到你的系統。

  • 你是否堅持在需要之後的很長時間內引用字符串圖像?
  • 您是否比創建圖片快得多?
  • 如果滾動字符串是會循環的字幕,那麼您是否可以將每個圖像緩存在循環中而不是繪製一個新的圖像?
  • 你可以建立一個圖像(或兩個環繞),只顯示相關部分通過移動你的控制和隱藏的東西后面的東西?
  • 你是否爲每個DrawText()調用創建一個新的字符串對象,而不是重新使用它們?
  • 您是否正在創建大量不需要的新字體對象(可能是每個字符一個)?
  • 最重要的是,您是否每次都繪製一個全新的位圖,或者您是否可以清除現有位圖並在其上繪製新字符串?
+0

一些在這裏的建議,謝謝。我嘗試過不使用全局字符串,並且每次都創建一個新的字符串。但是,這沒有什麼區別。 最重要的是,您是否每次都繪製一個全新的位圖,或者您是否可以清除現有位圖並在其上繪製新字符串? 對此不太清楚。如果我切成單獨的字符串,比如說,是面板寬度的兩倍,並將其滾動,我只會使用與所使用的最大字符串大小相同的內存。我將如何釋放DrawText在每個循環之後使用的mem?我覺得我正在做一些非常愚蠢的事情! – user183185 2009-11-12 18:31:46

+0

對不起,拼寫錯誤 – user183185 2009-11-12 18:33:04

+0

對不起,代碼中有一些噪音....我一直在玩它。 – user183185 2009-11-12 18:35:45