この知恵ノートを「知恵コレクション」に追加しました。
追加した知恵ノートはMy知恵袋の「知恵コレクション」ページで確認できます。
「知恵コレクション」に登録済みです。
再登録しました。
追加に失敗しました。
ノートに戻り、もう一度やり直してください。
すでに1,000件のノートが登録されています。
新しく追加したい場合は、My知恵袋の「知恵コレクション」ページで登録されているノートを削除してください。
追加できませんでした。
ノートは削除されました。
知恵コレに追加する:0人
C#でスレッド間をMonitorクラスを使って同期をとる。
ライター:abiko_tetuさん(最終更新日時:2013/4/2)投稿日:2013/3/8 アドバイス受付中!
- ナイス!:
1
- 閲覧数:64
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
C#でスレッド間をMonitorクラスを使って同期をとる。
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
「C#でスレッドを作成する方法」における一連の説明(知恵ノート)において、ここでは、
「C#でスレッド間をMonitorクラスを使って同期をとる」
について説明します。
総合の目次
本ページを含めた関連事項の総合目次です。
http://note.chiebukuro.yahoo.co.jp/detail/n1729
はじめに
あるスレッドと別なスレッドの間で、データーのやり取りをすると異常が発生します(うまくデーターが伝わらないことがある)。
そもそもスレッドとは、並列に実行される処理です。
よって、各スレッドは、勝手に(別々に)動作しているので、データーをやり取りすること自体が困難なことです。
そこで、各スレッド間で同期をとる機能(タイミングを合わせる機能)があります。
ここでは、その同期用機能のひとつであるMonitorクラスについて紹介します。
サンプルコード
ここで取り上げるサンプルは、なるべく複雑にならない範囲で、実際にスレッドの扱い方を確かめられるものとします。
本サンプの仕様
本サンプルでは、スレッド生成等の基本的なコードの書き方を紹介することが目的なので、単純な計算(足し算)をして、その計算結果をテキストボックスに表示するだけにしました。
具体的には、まず、テキストボックス textBox1 に、ユーザーが演算値1(例えば、7+12 ならば、7の方の値)を入力します。
次に、テキストボックス textBox2 に、ユーザーが演算値2(7+12 の12の方の値)を入力します。
次に、ボタン button1 をクリックすると、上記の入力値から、計算(足し算)を行ないます。
ここで、その計算処理は、スレッドを用意して、そのスレッドで計算をします。
また、演算値1、2の値は、Monitorクラスを使って、計算用スレッドに渡します。
その後計算処理が終わったら、その計算結果をテキストボックス textBox3 に表示します。
フォームデザイン等の前準備
コードを記述する前に、フォームのデザイン作成などの、以下の前準備を行なって下さい。
<プロジェクトの作成>
本サンプルの確認用に、新規にプロジェクトを作成して下さい。
プロジェクトの種類は、「Windowsフォームアプリケーション」です。
<フォームのデザイン>
デザイン画面で、TextBox (テキストボックス) を3個と、 Button (ボタン)を1個貼り付けて下さい。
<テキストボックスの複数行化>
テキストボックスは、デフォルトでは1行用になっています。
textBox1 と textBox2 は、デフォルト(1行表示用)のままで構いません。
しかし、textBox3 については、複数行の文字を扱いたいので、以下の操作で、テキストボックスを複数行対応にして下さい。
まず、先程貼り付けたテキストボックス textBox3 を選択状態にして下さい(すなわち、デザイン画面上のテキストボックス textBox3 をクリックする)。
そうすると、テキストボックスの右上に、小さな三角形のマークが表示されます。
それをクリックすると Multiline と言う表記のチェックボックスが表示されます。
そのチェックボックスにチェックを入れると、複数行対応になります。
あとは、デザイン画面のチェックボックスをマウス操作で、縦幅を広げて下さい。
<イベントプロシージャの作成>
デザイン画面のフォームをダブルクリックして、Form1_Load() メソッドを作って下さい。
また、先程貼り付けたデザイン画面上のボタン「button1」をダブルクリックして、button1_Click() メソッド を作って下さい。
<クラスを書くためのソースファイルの作成>
[プロジェクト] - [クラスの追加] で、「新しい項目の追加」画面を表示する。
その画面の [ファイル名]欄に任意のファイル名(クラス用ソースファイルのファイル名)を記入する。
[追加]ボタンをクリックする。
なお、ここで作成されたソースファイルには、後述しますクラスのコード(「演算値格納用クラスのコード」のコード)を記述します。
演算値格納用クラスのコード
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MonitorSimple
{
//===================================
// 演算値格納用クラス
//===================================
public class ThreadParameter
{
public float data1; // 演算値1
public float data2; // 演算値2
}
}
Formクラスのコード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
// C#でスレッド間をMonitorクラスを使って同期をとる。
namespace MonitorSimple
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// スレッドからテキストボックスをアクセスすることを指定
Control.CheckForIllegalCrossThreadCalls = false;
}
//============
// メンバー変数
private System.Threading.Thread ThreadMethodThread; // スレッド
private ThreadParameter ThreadPara; // 演算値1、2を格納するクラス
//============
// フォーム起動時イベント
private void Form1_Load(object sender, EventArgs e)
{
// 演算値格納用オブジェクトを生成
ThreadPara = new ThreadParameter();
// 演算値を初期設定
textBox1.Text = "7";
textBox2.Text = "12";
}
//============
// スレッド開始用ボタン
private void button1_Click(object sender, EventArgs e)
{
// ユーザー入力された演算値(string型)を数値(float型)に変換
float data1, data2; // 演算値1、2
float.TryParse(textBox1.Text, out data1); // 演算値1
float.TryParse(textBox2.Text, out data2); // 演算値2
// 演算値格納用オブジェクトのロック/解放待ち
// 他のスレッドがオブジェクトをアクセスしていない場合 ---> オブジェクトのロック
// 他のスレッドがオブジェクトをアクセスしている場合 ---> オブジェクトの解放待ち
System.Threading.Monitor.Enter(ThreadPara);
ThreadPara.data1 = data1; // 演算値1
ThreadPara.data2 = data2; // 演算値2
// 演算値格納用オブジェクトを解放
System.Threading.Monitor.Exit(ThreadPara);
// スレッド作成
// --- 対象処理用メソッドをスレッド用メソッドとして登録
ThreadMethodThread = new System.Threading.Thread(AddThreadMethod);
// スレッドを開始
ThreadMethodThread.Start();
}
//============
// 加算処理スレッド用メソッド
// --- 加算処理を行なうメソッドです。なお、本メソッドは、マルチスレッ
// ドとして処理が実行されます。
private void AddThreadMethod()
{
// スレッドに行なわせたい処理を記述する。
// ここでは、加算処理を行なわせるものとする。
// 演算値格納用オブジェクトのロック/解放待ち
// 他のスレッドがオブジェクトをアクセスしていない場合 ---> オブジェクトのロック
// 他のスレッドがオブジェクトをアクセスしている場合 ---> オブジェクトの解放待ち
System.Threading.Monitor.Enter(ThreadPara);
// 演算値を取得
float data1 = ThreadPara.data1; // 演算値1
float data2 = ThreadPara.data2; // 演算値2
// 演算値格納用オブジェクトを解放
System.Threading.Monitor.Exit(ThreadPara);
// 加算処理
float ThreadAnswer = data1 + data2;
// 計算結果表示
textBox3.Text += data1.ToString() + " + " + data2.ToString() + " = " + ThreadAnswer.ToString() + "\r\n";
}
}
}
実行結果
計算結果が表示されます。
さいごに
特になし。
アドバイス(このノートのライターへのメッセージ)を送る
このノートはどうでしたか? いいと思ったことや、こうしたらもっとよくなるといったメッセージを送りましょう! ノートの内容やライターについて質問がある場合は、Q&Aから質問してみましょう
アドバイスを送るには、
Yahoo! JAPAN IDでのログインおよび
Yahoo!知恵袋の利用登録が必要です。
感想アドバイス履歴
-
現在アドバイスはありません
このノートに関するQ&A
このノートに関するQ&Aは、まだありません。
あなたにおすすめの知恵ノート
あなたにおすすめのQ&A
- .NETのスレッド同期処理(クリティカルセクション)について VB、C#、C++(.NET2.0~.NET4)にて、マル...
- iPhone4Sを使っているんですが 今まで使っていたPCが壊れてしまいました そこで新しいPCでiTunesで同...
- iPod touch5使ってます ホームボタンが若干陥没しています。 完全に陥没しているわけではありません...
- いままでwindows vista を使っていましたが、imac 10.8.3を購入しました。そして今までwindows のitu...
- パズドラのデータについて I-fun box を使ってIPadとiPhoneをパズドラの データのみ同期して今は二...