CAD日記

AutoCAD,DXF,DWG,SXFなどCADのことから、仮想通貨や投資関係、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 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();
      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 を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

関連記事

no image

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

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

若いもんにC++を教えてやって、これまでやってきたことが少しでも伝わってくれればと願う夜

ファイルをセレクトするというC++で作ったActiveXのDLLのデバッグができないかと彼がおいらのところに来た時点で、そいつはなかなかチカラがあるなと感じた。

no image

UNICODE対応プログラム

開発環境:VC6 プリプロセッサの定義に、UNICODE,_UNICODEを追加。(_MBCSをカット) EXEの場合は、エントリポイントシンボルにwWinMainCRTStartupを記述。 ・ch …

PDFium ViewerによるPDFレンダリングがイケてる

PDFが電子ペーパーの絶対的な標準になったなか、PDFをプログラムであつかうのがとても簡単になってきた。

no image

Breaker

以前、Layout Breakerという名前のソフトを作ろうと考えていました。レイアウトはともかく、ブレーカー、つまり破壊者です。周囲の反対により、取り下げましたが、個人的にはけっこう気に入っていて、 …