[C#]非同期でSleep()したい時にはTask.Delay()を使う。

定周期処理を作るとき便利。

使い方は簡単です。
ボタンクリックしたら1秒おきにラベルに0~9までの文字を表示するプログラムを考えます。

Sleep()でやってた処理。

private async void button1_Click(object sender, EventArgs e)
{
    for (int i = 0; i < 10; i++)
    {
        await Task.Run(() => System.Threading.Thread.Sleep(1000));
        label1.Text = i.ToString();
    }
}

Task.Delay()を使う場合。

private async void button1_Click(object sender, EventArgs e)
{
    for (int i = 0; i < 10; i++)
    {
        await Task.Delay(1000);
        label1.Text = i.ToString();
    }
}

実践プログラミング。指定されたIPアドレスに対して1秒周期でPingを送信して死活監視を行う。
以前、同じようなプログラムを作って、えらいめんどくさい思い出があったのですが、async/awaitを使用すると驚くほど簡単に出来ます。

実行画面

ソース

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace async_ping
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
        }

        private async void Ping(TextBox tbox)
        {
            Color setcolor = Color.WhiteSmoke;
            if (tbox.Text == "") goto CHANGECOLOR;
            try
            {
                System.Net.IPAddress ipAdr;
                var ipchk = System.Net.IPAddress.TryParse(tbox.Text,out ipAdr);
                if(ipchk ==false) goto CHANGECOLOR;

                var reply = await (new System.Net.NetworkInformation.Ping()).SendPingAsync(ipAdr, 1000);

                if (reply.Status == System.Net.NetworkInformation.IPStatus.Success)
                {
                    setcolor = Color.Lime;
                }
                else
                {
                    setcolor = Color.Red;
                }
            }
            catch
            {
                setcolor = Color.WhiteSmoke;
            }
CHANGECOLOR:
            tbox.BackColor = setcolor;
        }

        private async void Form1_Load(object sender, EventArgs e)
        {
            LoadSaveValue(isLoad: true);

            while (true)
            {
                await Task.Delay(1000);
                foreach (var ctrl in this.Controls)
                {
                    var tbox = ctrl as TextBox;
                    if (tbox != null)
                    {
                        Ping(tbox);
                    }
                }
            }
        }
        private const string SAVEFILE = "savefile.csv";
        private void LoadSaveValue(bool isLoad = false, bool isSave = false)
        {
            if (isLoad)
            {
                if(System.IO.File.Exists(SAVEFILE))
                {
                    var vals = System.IO.File.ReadAllText(SAVEFILE).Split(',');
                    textBox1.Text = vals[0];
                    textBox2.Text = vals[1];
                    textBox3.Text = vals[2];
                    textBox4.Text = vals[3];
                    textBox5.Text = vals[4];
                    textBox6.Text = vals[5];
                    textBox7.Text = vals[6];
                    textBox8.Text = vals[7];
                }
            }
            else if (isSave)
            {
                var s = string.Format("{0},{1},{2},{3},{4},{5},{6},{7}",
                    textBox1.Text,
                    textBox2.Text,
                    textBox3.Text,
                    textBox4.Text,
                    textBox5.Text,
                    textBox6.Text,
                    textBox7.Text,
                    textBox8.Text);
                System.IO.File.WriteAllText(SAVEFILE,s);
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            LoadSaveValue(isSave: true);
        }
    }
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


This blog is kept spam free by WP-SpamFree.