- PR -

CPU負荷を消費せずタイマー割り込みを待つ方法(C#)

投稿者投稿内容
ひろし
会議室デビュー日: 2003/03/18
投稿数: 13
投稿日時: 2003-06-25 17:49
タイマー割り込み処理をしたいと望んでいます。
C#での記述について2点(Q1.Q2)分かりません。
アドバイスを願います。

Q1.イベントを待つためのループはどう記述すれば良いでしょうか?
   ・無駄なCPU負荷を発生させないで待つ方法を知りたい。
   ・VBの場合、サプルーチンを抜けても"End"命令がこない限り
    終了せずタイマー割り込みを受けてくれますが、C#の場合、
    終了してしまいます。どうすれば良いでしょうか?

Q2.画面表示の更新や他プロセスの円滑な処理のためにイベントを
   発生させたいのですが、どうすれば良いでしょうか?
   ・VBの時は、所々に"DoEvents"を挿入していました。

// 試みに簡単な例題を作成してみました。
// "Start"ボタンを押すと1秒ごとに現在時刻を表示しはじめる
private void buttonStart_Click(object sender, System.EventArgs e)
{
timer1.Interval=1000;
timer1.Enabled=true;
timer1.Start();

label1.Text ="Start";
while(FlagStop==false)
{
// Stopボタンが押されるまで待つ
// 待つ間は1秒ごとに画面を更新する
// 空回し等による無駄なCPU負荷をかけたく無い
// *** Q1ここをどう記述して良いか分からない ***
}
timer1.Stop();
timer1.Enabled=false;
label1.Text ="Stop";
}
// "Stop"ボタンを押すと処理を停止する
private void buttonStop_Click(object sender, System.EventArgs e)
{
FlagStop=true;
}

// 1秒ごとに画面を更新する
private void timer1_Tick(object sender, System.EventArgs e)
{
DateTime t = new DateTime.Now;
label1.Text =t.ToShortTimeString();
// 画面の表示を更新したい
// *** Q2.ここをどう記述して良いか分からない ***
}


石野 光仁
会議室デビュー日: 2002/04/18
投稿数: 18
投稿日時: 2003-06-25 18:37
こんにちは、
見たソースを切り貼りしただけですので、正しく動くか
わかりませんが、こんな感じでは駄目でしょうか?

// 試みに簡単な例題を作成してみました。
// "Start"ボタンを押すと1秒ごとに現在時刻を表示しはじめる
private void buttonStart_Click(object sender, System.EventArgs e)
{
timer1.Interval=1000;
timer1.Enabled=true;
timer1.Start();

label1.Text ="Start";
}
// "Stop"ボタンを押すと処理を停止する
private void buttonStop_Click(object sender, System.EventArgs e)
{
timer1.Stop();
timer1.Enabled=false;
label1.Text ="Stop";
}

// 1秒ごとに画面を更新する
private void timer1_Tick(object sender, System.EventArgs e)
{
DateTime t = new DateTime.Now;
label1.Text =t.ToShortTimeString();
}
ひろし
会議室デビュー日: 2003/03/18
投稿数: 13
投稿日時: 2003-06-26 10:14
ご返答ありがとうございます。
ご返答にありましたソースコードでためしたところ、
期待通りの動きをしてくれました。
この返答プログラムでは必要ありませんが、
依然としてDoEvents相当の機能については知る必要があります。
ループが重い場合、DoEvents相当の機能が無いと
画面更新やボタンが押されたことの検知等の
応答性が低下してしまいます。
とりあえず、あまり複雑な処理はしたくないのですが…。
アドバイスお願いします。
石野 光仁
会議室デビュー日: 2002/04/18
投稿数: 18
投稿日時: 2003-06-26 10:32
うまくいってよかったです。

動作中に、他の処理を動かすのならば、スレッドとかを利用してみたら
どうでしょうか?
(私は.NETでスレッドはまだ利用していませんが・・・)

#最初のプログラムを見て、あっ割り込みの処理だ なんて懐かしく思いました。
#昔、キーボード割り込み? で上がってきた内容をメモリに保存してそれを
#確認しながら動くっていうプログラムを組んでいたんですよね。
#アスキーの青い本を見ていた頃が懐かしいです…
#何とかテクニカルマニュアル? だったかな?
rvmx
大ベテラン
会議室デビュー日: 2002/09/26
投稿数: 184
お住まい・勤務地: 愛媛県
投稿日時: 2003-06-26 11:15
今日は

VB6.0 のDoEventsに相当する機能は、Application.Doevents()だと思いますが。
また、System.Threading.Thread.Sleep(*) *msと組み合わせれば、より効果的に
CPUの負荷をOS?側に振り分けられると思うのですが。
NothingButXMLInfoSet
ベテラン
会議室デビュー日: 2003/03/31
投稿数: 65
投稿日時: 2003-06-26 11:57
.NET Frameworkのスレッドプールを利用するこんな方法もあります。

コード:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;

class Form1 : Form {
    static void Main() {
        Application.Run(new Form1());
    }
    
    Label label1;
    Form1() {
        label1 = new Label();
        Button btn1 = new Button();
        btn1.Text = "Start";
        btn1.Left = label1.Width;
        btn1.Click += new EventHandler(Start);
        Button btn2 = new Button();
        btn2.Text = "Stop";
        btn2.Left = label1.Width + btn1.Width;
        btn2.Click += new EventHandler(Stop);
        Controls.AddRange(new Control[]{ label1, btn1, btn2 });
        this.Closing += new System.ComponentModel.CancelEventHandler(ClosingForm);
    }
    
    void ClosingForm(object o, System.ComponentModel.CancelEventArgs e) {
        timer1.Change(Timeout.Infinite, 0);  
    }
    
    delegate void SetTextDelegate(string data);
    
    void SetText(string data) {
        label1.Text = data;
    }
    
    void Tick(object state) {
        SetTextDelegate std = new SetTextDelegate(SetText);
        this.Invoke(std, new object[]{ DateTime.Now.ToLongTimeString() });
    }

    System.Threading.Timer timer1;
    void Start(object o, EventArgs e) {
        timer1 = new System.Threading.Timer(
            new TimerCallback(Tick), null, Timeout.Infinite, 1000);
        timer1.Change(0, 1000);
        BackColor = Color.Green;
    }

    void Stop(object o, EventArgs e) {
        timer1.Change(Timeout.Infinite, 0);
        BackColor = SystemColors.Control;
    }
}

ひろし
ぬし
会議室デビュー日: 2002/09/16
投稿数: 390
お住まい・勤務地: 兵庫県
投稿日時: 2003-06-27 01:07
ご返答ありがとうございます。とりあえず問題を解決できそうです。

それから、一番最初の質問で下記のように書きましたが、

>Q1.イベントを待つためのループはどう記述すれば良いでしょうか?
>   ・無駄なCPU負荷を発生させないで待つ方法を知りたい。
>   ・VBの場合、サプルーチンを抜けても"End"命令がこない限り
>    終了せずタイマー割り込みを受けてくれますが、C#の場合、
>    終了してしまいます。どうすれば良いでしょうか?

わたしの思い違いの部分があることに気がつきました。(下記)
C#の実プログラムではDLLを呼び出しているのですが、As Any表現を移植した部分で
落ちていたことに気がつきました。混乱させてすみませんでした。

>    終了せずタイマー割り込みを受けてくれますが、C#の場合、
>    終了してしまいます。←コレウソ
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2003-06-27 09:52
ちょっと質問です。
引用:

NothingButXMLInfoSetさんの書き込み (2003-06-26 11:57) より:
.NET Frameworkのスレッドプールを利用するこんな方法もあります。
</PRE><HR SIZE="1" WIDTH="100%"></TD></TR></TABLE><!-- BBCode End -->


私の読解不足かもしれませんが、どこかでスレッドプールを利用してます?

スキルアップ/キャリアアップ(JOB@IT)