CAD日記

主にAutoCADのことについて書いているけど、近頃は投資系ネタに注力している。自動売買、仮想通貨、PC関係、プログラミングなど。@caddiary

ソフト開発

マルチスレッドプログラミング(C#編)

投稿日:2018年8月12日 更新日:

マルチスレッドプログラミング(C++編)
マルチスレッドプログラミング(VB.net編)
に続く第三弾はC#編。

前の2回は昔ながらのThreadクラス(System.Threading名前空間)していたが、async(エイシンク)/await(アウェイト)という最新の技術をC#で実現してみた。いや、実際のところはおいらが書いたわけではない。とあるプログラム博士にVB.netで書いてもらったのを、C#に変換してちょいと手を入れてみただけ。この程度の改修であっても、アラフィフプログラマのおいらにとっては充実感のある活動となった。こういうきっかけがあると、今後自分でもC#やVBのプログラムをいじってみる気になるかもしれない。async/awaitは最新技術なだけあって、VisualStudio2012以降じゃないと使えないってことだったので、前2回のVS2010ではなく最新のVS2017を使ってみた。こういう最新の開発環境に触れられたのも大きいな。

画面設計とソースコードは以下の通りで、Visual Studio 2017 C#のプロジェクト一式はこちら。

Imports System.Threading
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;
using System.Threading;

namespace ThreadTestCSAsync
{
  public partial class Form1 : Form
  {
    private int count = 0;
    private bool exec = false;
    private CancellationTokenSource canceled;
    private TaskCompletionSource<bool> waitForStop;
    protected override void WndProc(ref Message m)  // 実行中はクローズボタンを無効にする
    {
      const int WM_SYSCOMMAND = 0x112;
      const long SC_CLOSE = 0xF060L;
      if (exec == true && m.Msg == WM_SYSCOMMAND && (m.WParam.ToInt64() & 0xFFF0L) == SC_CLOSE)
        return;
      base.WndProc(ref m);
    }
    public Form1()
    {
      InitializeComponent();
      MaximizeBox = false;
    }
    private async void button1_Click(object sender, EventArgs e)
    {
      if (canceled != null)
        return;
      ClearCount();
      button1.Enabled = false;
      button2.Enabled = true;
      exec = true;
      canceled = new CancellationTokenSource();
      try
      {
        int i;
        for (i = 1; i <= 10; i++)
        {
          IncrementCount();
          await Task.Run(() =>
          {
            Thread.Sleep(3000);
          });
          if (waitForStop != null)
            await waitForStop.Task;
          canceled.Token.ThrowIfCancellationRequested();
        }
        MessageBox.Show("正常終了", "情報", MessageBoxButtons.OK, MessageBoxIcon.Information);
      }
      catch (OperationCanceledException)
      {
        ClearCount();
        MessageBox.Show("中止", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      catch (Exception)
      {
        ClearCount();
        MessageBox.Show("異常終了", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
      finally
      {
        canceled = null;
        button1.Enabled = true;
        button2.Enabled = false;
        exec = false;
      }
    }
    private void button2_Click(object sender, EventArgs e)
    {
      if (waitForStop != null)
        return;
      waitForStop = new TaskCompletionSource<bool>();
      try
      {
        if (MessageBox.Show("中止しますか?", "質問", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
        {
          if (canceled != null)
          {
            canceled.Cancel();
            button2.Enabled = false;
          }
        }
      }
      finally
      {
        waitForStop.SetResult(true);
        waitForStop = null;
      }
    }
    private void ClearCount()
    {
      count = 0;
      UpdateText();
    }
    private void IncrementCount()
    {
      count = count + 1;
      UpdateText();
    }
    private void UpdateText()
    {
      label1.Text = string.Format("時間のかかる処理を実行中。{0}/10", count);
    }
  }
}

プログラムってのはホントおもしろいよなぁ。最近は仕事でプログラムをやらなくなったから、プログラムをつくることの喜びを忘れていた。こうやって休日に家でプログラムをやっているというのは仕事というわけではなく、あくまで趣味。少なくとも今の仕事に生かすつもりはなくて、純粋に自分の楽しみ。もしかしたら、今の仕事と全く別で役に立つかもしれないという色気もあるし、さらに言えばこの記事を読んで助かったという人間が1人でもいればよい。ググれば何でも出てくる時代でも、こういう要求はネット上にピンポイントで転がっていないわけだから誰かの役に立つことと思う。そうやって少しでもアクセス件数が増えて、Adsenseの収益が上がることももちろん期待している。

-ソフト開発

執筆者:


comment

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

関連記事

高速なPDFビューアをC#とPDFiumでサクっと作ってみよう!

どんなPDFビューアを作ったのかというと、こんなモノ。 開いたPDFがCADの図面っぽいが、れっきとしたPDFファイルであり、ベクトル情報をちゃんと表現しているかを明らかにしたかったので使ったデータ。 …

秀丸マクロ第3弾は「指定した列数、レコード数でCSVファイルを作る」

秀丸マクロがおもしろいという記事を書いて以来、何か要件はないだろうかとさがしていた。 秀丸マクロがおもしろくて練習のため2つのマクロを作ってみた 「指定した列数、レコード数でCSVファイルを作る」なん …

no image

アプリでzip圧縮と解凍をやりたくてzlibを組み込んでみたんだけど。。

でかいファイルは、圧縮してコンパクトに扱いたくなる。 テキスト形式で定義されているファイルをアプリで読み書きする。 テキストは圧縮すれば1/5くらいになるので、その結果小さくなった ファイルをアプリの …

Windowsアプリで引数を受け取る(改)

MFCを使ったWindowsアプリの実装に関する話。 CWinAppを継承したクラスでは、m_lpCmdLineで起動時のパラメータを取得できる。そのパラメータは1個の文字列だが、半角スペースで区切ら …

PDFアレコレVer1.01リリース

趣味のプログラムってホント楽しくて、平日の夜中だってのに眠りを忘れて取り組んでしまった。