回答編集履歴

4 コード改善

ozwk

ozwk score 7443

2016/11/08 13:35  投稿

> 考えているのは、「マウスホイールのように速い間隔で連続して値が変化しているときは、一定間隔で値を拾うようにしてBitmap生成の回数を減らす」という感じです。
前回描画した時刻を保持しておいて、
numericUpDownのイベントが発生した時刻と比べて、
一定時間経っていたら描画する。
時刻はDateTime.Nowでとれます。
Timerで監視すればいいでしょう。
面倒なのでRxのThrottle使ったほうが簡潔ですが。
---
(NuGetからSystem.Reactiveを追加して)
```C#
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Reactive.Linq;
namespace WindowsFormsApplication1
{
   public partial class Form1 : Form
   {
 
       // initialize  
       public Form1()
       {
           InitializeComponent();
           Observable.FromEvent<EventHandler, EventArgs>(
               h => (sender, e) => h(e), h => numericUpDown1.ValueChanged += h, h => numericUpDown1.ValueChanged -= h)
               .Throttle(TimeSpan.FromMilliseconds(500)) // 動作がわかりやすいようにわざと大きめの値を入れている
               .Throttle(TimeSpan.FromMilliseconds(500)) // 動作がわかりやすいように、わざと大きめの値を入れている
               .ObserveOn(System.Threading.SynchronizationContext.Current) // UIスレッドで監視
               .Subscribe(_ => numericUpDown1_Changed());
 
 
             
       }
       private void numericUpDown1_Changed() // これはnumericupDown1のイベントから外しておく
       
       private void numericUpDown1_Changed() // イベントから外しておく
       {
           int length = Convert.ToInt32(numericUpDown1.Value);
             
           pictureBox1.Image = MakeBmp(length);
           label1.Text = length.ToString(); // 確認用に追加  
       }
       
       private Bitmap MakeBmp(int length)
       {
           Bitmap bmp = new Bitmap(pictureBox1.Size.Width, pictureBox1.Size.Height);
           using (Graphics g_bmp = Graphics.FromImage(bmp))
           {
               g_bmp.FillRectangle(Brushes.Red, new Rectangle(0, 0, length, length));
           }
           return bmp;
       }
   }
}
```
3 ミス修正

ozwk

ozwk score 7443

2016/11/08 13:28  投稿

> 考えているのは、「マウスホイールのように速い間隔で連続して値が変化しているときは、一定間隔で値を拾うようにしてBitmap生成の回数を減らす」という感じです。
前回描画した時刻を保持しておいて、
numericUpDownのイベントが発生した時刻と比べて、
一定時間経っていたら描画する。
時刻はDateTime.Nowでとれます。
Timerで監視すればいいでしょう。
面倒なのでRxのThrottle使ったほうが簡潔ですが。
---
(NuGetからSystem.Reactiveを追加して)
```C#
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Reactive.Linq;
namespace WindowsFormsApplication1
{
   public partial class Form1 : Form
   {
       public Form1()
       {
           InitializeComponent();  
           Observable.FromEvent<EventHandler, EventArgs>(
               h => (sender, e) => h(e), h => numericUpDown1.ValueChanged += h, h => numericUpDown1.ValueChanged -= h)
               .Throttle(TimeSpan.FromMilliseconds(500)) // 動作がわかりやすいようにわざと大きめの値を入れている
               .Subscribe(_ => numericUpDown1_Changed());
           InitializeComponent();
           
       }
       private void numericUpDown1_Changed() // これはnumericupDown1のイベントから外しておく
       {
           int length = Convert.ToInt32(numericUpDown1.Value);
           pictureBox1.Image = MakeBmp(length);
       }
       private Bitmap MakeBmp(int length)
       {
           Bitmap bmp = new Bitmap(pictureBox1.Size.Width, pictureBox1.Size.Height);
           using (Graphics g_bmp = Graphics.FromImage(bmp))
           {
               g_bmp.FillRectangle(Brushes.Red, new Rectangle(0, 0, length, length));
           }
           return bmp;
       }
   }
}
```
2 Rx追記

ozwk

ozwk score 7443

2016/11/08 13:27  投稿

> 考えているのは、「マウスホイールのように速い間隔で連続して値が変化しているときは、一定間隔で値を拾うようにしてBitmap生成の回数を減らす」という感じです。
前回描画した時刻を保持しておいて、
numericUpDownのイベントが発生した時刻と比べて、
一定時間経っていたら描画する。
時刻はDateTime.Nowでとれます。
Timerで監視すればいいでしょう。
面倒なのでRxのThrottle使ったほうが簡潔ですが。
面倒なのでRxのThrottle使ったほうが簡潔ですが。
---
(NuGetからSystem.Reactiveを追加して)
```C#
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Reactive.Linq;
namespace WindowsFormsApplication1
{
   public partial class Form1 : Form
   {
       public Form1()
       {
           Observable.FromEvent<EventHandler, EventArgs>(
               h => (sender, e) => h(e), h => numericUpDown1.ValueChanged += h, h => numericUpDown1.ValueChanged -= h)
               .Throttle(TimeSpan.FromMilliseconds(500)) // 動作がわかりやすいようにわざと大きめの値を入れている
               .Subscribe(_ => numericUpDown1_Changed());
           InitializeComponent();
       }
       private void numericUpDown1_Changed() // これはnumericupDown1のイベントから外しておく
       {
           int length = Convert.ToInt32(numericUpDown1.Value);
           pictureBox1.Image = MakeBmp(length);
       }
       private Bitmap MakeBmp(int length)
       {
           Bitmap bmp = new Bitmap(pictureBox1.Size.Width, pictureBox1.Size.Height);
           using (Graphics g_bmp = Graphics.FromImage(bmp))
           {
               g_bmp.FillRectangle(Brushes.Red, new Rectangle(0, 0, length, length));
           }
           return bmp;
       }
   }
}
```
1 追記

ozwk

ozwk score 7443

2016/11/08 13:10  投稿

> 考えているのは、「マウスホイールのように速い間隔で連続して値が変化しているときは、一定間隔で値を拾うようにしてBitmap生成の回数を減らす」という感じです。
前回描画した時刻を保持しておいて、
numericUpDownのイベントが発生した時刻と比べて、
一定時間経っていたら描画する。
時刻はDateTime.Nowでとれます。
時刻はDateTime.Nowでとれます。
Timerで監視すればいいでしょう。
面倒なのでRxのThrottle使ったほうが簡潔ですが。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る