2017-10-26 2 views
0

私はwinformsプロジェクトでフォームに追加した2つのUserControlを持っています.1つは文字列を描画して右から左へスクロールし、他の文字列を描画し、その間にInvalidate()を呼び出すことによって、下から上へとスクロールします。(true)loop.But私の文字列が長すぎると、約1000文字のUIスレッドがブロックされます。私の質問は:私は間違って何をしていますか?テキストをスクロールさせるより良い方法はありますか? と怒鳴るが、コードの私の抜粋です:コメントで述べたように文字列が長すぎる場合、Onpaint()ブロックのUIスレッドで文字列を描画

int scrollTextSpeed = 100; 
bool scrollingText = true; 
Thread updateUI ; 

void init(){ 
    updateUI = new Thread(updateScrollText); 
    updateUI.Start(); 
} 

void updateScrollText() 
    { 
     while (true) 
     { 
      if (scrollingText) { 

       Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal, 
       new MethodInvoker(Invalidate)); 
       Thread.Sleep(scrollTextSpeed); 
      } 
     } 
    } 


protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) 
    { 

     SizeF stringSize = e.Graphics.MeasureString(text, this.Font); 

     var yPos = (this.ClientSize.Height/2) - (stringSize.Height/2); 
     e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias; 
     e.Graphics.DrawString(text, this.Font, brus, 
     currentPos, yPos); 
     if (fisttime) 
     { 
      currentPos = this.ClientSize.Width - 1; 
      fisttime = false; 
     } 
     else 
     { 
      if (currentPos < (-1 * (stringSize.Width))) 
       currentPos = this.ClientSize.Width - 1; 
      else 
       currentPos -= scrollPixelDistance; 
     } 
    } 
+4

ビジーープルでは無効にしないでください。意味はありません。タイマーは存在します。それが変化しなければ、毎回文字列を測定することも意味がありません。あなたがビットマップとしてそれを保つことができるので、毎回描画しないでください –

+0

なぜあなたはテキストを描画していますか?なぜ 'Label'を使わないのですか? – Enigmativity

+0

新しいWinFormsプロジェクトにコードを貼り付けてコンパイルしました。これは50000文字の文字列でスクロールし続け、フォームは依然としてユーザー入力に応答します。 –

答えて

1

、私は、UIスレッドがブロックしている問題を再現することはできません。しかし、私はコードのこの部分をリファクタリングする必要があると思います。これはおそらくブロッキングUIの問題を解決するでしょう。

現在のところ、スクロール速度は、UIスレッドがInvalidate()要求で動作すると決めるたびに直接的に異なります。さらに、複数のスクロールテキストがあることを示しているため、これらのテキストの異なるスクロール速度を設定することはほとんど不可能です。あなたが任意の時点でテキストをスクロールの位置を決定することができます数学のビットで

、すなわち:

float x = ClientRectangle.Width - (((uint)Environment.TickCount/40f) % 
     (stringSize.Width + ClientRectangle.Width)); 

今すぐスクロール位置はもはやリフレッシュレートに依存していること、あなたが複数の必要はありませんタイマー。また、単純なSystem.Windows.Forms.Timerでは、別のスレッドから何も呼び出す必要はありません。

関連する問題