【.NET Framework】Progress<T>を使ったProgressBarのサンプル

.NET Framework コンピュータ
.NET Framework
WinFormなどで重い処理を行う場合、利用者の操作を妨げないようにasyncとawaitを使って別スレッドで実行すると良いらしいです。(あまり深く理解はしていないのですが…)
重い処理で時間がかかる場合、利用者に進捗状況をお知らせしてあげると親切です。ということでプログレスバーで進捗状況を表示するサンプルを用意してみました。

ソースコード

using System.Runtime.CompilerServices;
using System.Net;
using System.ComponentModel;
using System.Diagnostics;
using System;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;

// ProgressBar Sample

class Form1 : Form
{
    ProgressBar ProgressBar1 = new ProgressBar
    {
        Width = 240,
        Height = 40,
        Left = 20,
        Top = 20,
    };

    Button Button1 = new Button
    {
        Width = 40,
        Height = 40,
        Left = 220,
        Top = 80,

        Text = "開始",
    };
    
    public void HeavyTask(IProgress<int> progress)
    {
        for (var i = 1; i < 100; i++)
        {
            Thread.Sleep(100);
            progress.Report(i); // 進捗を報告
        }
    }
    private async void eventButton1Click(Object s, EventArgs e)
    {
        ProgressBar1.Value = 0; // プログレスバーの初期化

        var progress = new Progress<int>(x => {
            ProgressBar1.Value = x; // 進捗を管理するオブジェクト(progress)の値とプログレスバーの値を紐づけ
        });
        
        await Task.Run(() => HeavyTask(progress));
    }

    Form1()
    {
        Button1.Click += eventButton1Click;

        Controls.AddRange(new Control[]{ProgressBar1, Button1});
    }
    [STAThread]
    static void Main()
    {
        Application.Run(new Form1());
    }
}

コンパイル

.NET Framework

csc /t:winexe Progress.cs

mono

mcs ./Progress.cs /r:System.Windows.Forms.dll

実行

.NET Framework

./Progress.exe

mono

mono Progress.exe
「開始」ボダンを押す

プログレスバーのメモリが増える

終了

動作だけ見るとプログレスバーのメモリを増やしているだけですが、よくよく考えると、UIスレッドとは別のスレッドからInvokeを使わずにUIであるプログレスバーを操作しています。

コメント