WinFormsでの非同期処理 (async/await) チュートリアル

このチュートリアルでは、WinFormsアプリでの非同期処理 (async/await) の基本と応用 を、検証できるサンプルコード付き で学びます。

🎯 目標

  1. 同期処理と非同期処理の違いを実験(アプリのフリーズを確認)
  2. 時間がかかる処理を非同期で実行(ボタンを押して3秒後にラベルを更新)
  3. APIリクエストを非同期で実行(天気情報を取得)

📌 ステップ 1:プロジェクトの準備

  1. Visual Studio を開き、Windows フォーム アプリ (.NET) プロジェクトを作成
  2. フォームに以下のコントロールを配置
  • ボタン1 (btnSync) : 同期処理を実行
  • ボタン2 (btnAsync) : 非同期処理を実行
  • ボタン3 (btnApiRequest) : APIリクエストを非同期で実行
  • ラベル (labelStatus) : 処理の状態を表示

🔍 ステップ 2:同期処理の動作確認

まずは、同期処理(UIが固まる例) を作成します。

📌 コード(フリーズする処理)

private void btnSync_Click(object sender, EventArgs e)
{
    labelStatus.Text = "処理中...(UIがフリーズします)";
    System.Threading.Thread.Sleep(3000); // 3秒待機(UIが固まる)
    labelStatus.Text = "処理完了!";
}

Thread.Sleep(3000); を使うと UIが完全にフリーズする ため、labelStatus.Text = "処理中..."; すら表示されません。

これは、メインスレッド(UIスレッド)がブロックされる ため、ラベルの変更が 画面に反映される前にスリープに入る からです。

もし 同期処理で「処理中…」を表示してから遅延させる 方法を試したい場合、Application.DoEvents() を使うことで一時的にUIを更新できます。

private void btnSync_Click(object sender, EventArgs e)
{
    labelStatus.Text = "処理中...(UIがフリーズします)";
    Application.DoEvents(); // UIを強制的に更新
    System.Threading.Thread.Sleep(3000); // 3秒待機(UIは固まる)
    labelStatus.Text = "処理完了!";
}

💡 ポイント

  • Application.DoEvents(); を追加すると、「処理中…」の表示が反映される
  • ただし、その後 Thread.Sleep(3000); でフリーズするため、根本的な解決にはならない

💡 実験結果

  • Thread.Sleep(3000); の間、アプリが固まる
  • ボタンも押せず、「応答なし」になる

⚡ ステップ 3:非同期処理でフリーズを防ぐ

次に、非同期処理 (async/await) を使ってフリーズしない方法 を試します。

📌 コード(非同期で3秒待機)

private async void btnAsync_Click(object sender, EventArgs e)
{
    labelStatus.Text = "処理中...(UIは動きます)";
    await Task.Delay(3000); // 3秒待機(非同期)
    labelStatus.Text = "処理完了!";
}

実験結果

  • await Task.Delay(3000); の間も ボタンが押せる
  • アプリがフリーズしない!

🌍 ステップ 4:APIリクエストを非同期で実行

次に、天気情報を取得するAPIリクエストを非同期で実行します。

📌 コード(非同期APIリクエスト)

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Forms;

public partial class MainForm : Form
{
    private static readonly HttpClient client = new HttpClient();

    public MainForm()
    {
        InitializeComponent();
    }

    private async void btnApiRequest_Click(object sender, EventArgs e)
    {
        labelStatus.Text = "天気情報取得中...";

        try
        {
            // 非同期でAPIリクエストを送信
            string result = await client.GetStringAsync(/*サーバーのURL*/);

            // 取得したデータを表示
            labelStatus.Text = "天気情報: " + result;
        }
        catch (HttpRequestException)
        {
            labelStatus.Text = "通信エラー。インターネット接続を確認してください。";
        }
    }
}

実験結果

  • 天気情報が表示される
  • 取得中もボタンが押せる

🎯 まとめ

実験方法結果
同期処理(フリーズ)Thread.Sleep(3000);UIが固まる
非同期処理(フリーズしない)await Task.Delay(3000);UIが動く
APIリクエスト(非同期)await client.GetStringAsync(url);UIが固まらず通信可能

このように、async/await を使うとWinFormsアプリの操作性が向上 します!
📌 このサンプルを実行して、非同期処理の効果を体感してください! 🚀

C#,非同期

Posted by hidepon