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であるプログレスバーを操作しています。
コメント