atwiki-logo
  • 新規作成
    • 新規ページ作成
    • 新規ページ作成(その他)
      • このページをコピーして新規ページ作成
      • このウィキ内の別ページをコピーして新規ページ作成
      • このページの子ページを作成
    • 新規ウィキ作成
  • 編集
    • ページ編集
    • ページ編集(簡易版)
    • ページ名変更
    • メニュー非表示でページ編集
    • ページの閲覧/編集権限変更
    • ページの編集モード変更
    • このページにファイルをアップロード
    • メニューを編集
    • 右メニューを編集
  • バージョン管理
    • 最新版変更点(差分)
    • 編集履歴(バックアップ)
    • アップロードファイル履歴
    • ページ操作履歴
  • ページ一覧
    • ページ一覧
    • このウィキのタグ一覧
    • このウィキのタグ(更新順)
    • このページの全コメント一覧
    • このウィキの全コメント一覧
    • おまかせページ移動
  • RSS
    • このウィキの更新情報RSS
    • このウィキ新着ページRSS
  • ヘルプ
    • ご利用ガイド
    • Wiki初心者向けガイド(基本操作)
    • このウィキの管理者に連絡
    • 運営会社に連絡(不具合、障害など)
ページ検索 メニュー
プログラミング図書館・本館
  • ウィキ募集バナー
  • 目安箱バナー
  • 操作ガイド
  • 新規作成
  • 編集する
  • 全ページ一覧
  • 登録/ログイン
ページ一覧
プログラミング図書館・本館
  • ウィキ募集バナー
  • 目安箱バナー
  • 操作ガイド
  • 新規作成
  • 編集する
  • 全ページ一覧
  • 登録/ログイン
ページ一覧
プログラミング図書館・本館
ページ検索 メニュー
  • 新規作成
  • 編集する
  • 登録/ログイン
  • 管理メニュー
管理メニュー
  • 新規作成
    • 新規ページ作成
    • 新規ページ作成(その他)
      • このページをコピーして新規ページ作成
      • このウィキ内の別ページをコピーして新規ページ作成
      • このページの子ページを作成
    • 新規ウィキ作成
  • 編集
    • ページ編集
    • ページ編集(簡易版)
    • ページ名変更
    • メニュー非表示でページ編集
    • ページの閲覧/編集権限変更
    • ページの編集モード変更
    • このページにファイルをアップロード
    • メニューを編集
    • 右メニューを編集
  • バージョン管理
    • 最新版変更点(差分)
    • 編集履歴(バックアップ)
    • アップロードファイル履歴
    • ページ操作履歴
  • ページ一覧
    • このウィキの全ページ一覧
    • このウィキのタグ一覧
    • このウィキのタグ一覧(更新順)
    • このページの全コメント一覧
    • このウィキの全コメント一覧
    • おまかせページ移動
  • RSS
    • このwikiの更新情報RSS
    • このwikiの新着ページRSS
  • ヘルプ
    • ご利用ガイド
    • Wiki初心者向けガイド(基本操作)
    • このウィキの管理者に連絡
    • 運営会社に連絡する(不具合、障害など)
  • atwiki
  • プログラミング図書館・本館
  • .NET
  • スレッド

スレッド

最終更新:2011年01月25日 01:51

atachi

- view
管理者のみ編集可
  • スレッドの使用方法 [#o19b6a8c]
  • スレッドの待機 [#b547f148]
  • スレッドの中断要求 [#pa89cd17]
  • スレッドの中止要求 [#j360acf7]
  • UIスレッドとの関連 [#me832d5f]
  • タイマー使用方法 [#xaee2e70]

スレッドの使用方法

スレッドはThreadクラスを使用して作成します。
Thread.Start()を呼び出したタイミングでスレッドが作成され実行を開始します。

スレッドとして処理を行うメソッドは静的メソッドやインスタンスメソッドを呼び出すことができます。
インスタンスメソッドの場合、thisにあたるインスタンスやそのインスタンスが持つメンバが複数のスレッドで共有されるため、それらへアクセスを行う場合は排他制御が必要となります。

public class MyThreadClass {
	public static void StaticMethod() {
		Console.WriteLine("静的メソッドの呼び出し");
 
		Thread.Sleep(5000); // 5秒待機
 
		Console.WriteLine("静的メソッド終了");
	}
 
	public void InstanceMethod() {
		Console.WriteLine("インスタンスメソッドの呼び出し");
 
		Thread.Sleep(5000); // 5秒待機
 
		Console.WriteLine("インスタンスメソッド終了");
	}
}
 
public class MainApp {
	public static int Main(String[] args) {
		// インスタンスを作成し、インスタンスメソッドを別スレッドで実行
		MyThreadClass obj = new MyThreadClass();
 
		Thread instanceThread = new Thread( obj.InstanceMethod );
		instanceThread.Start();
 
		// 静的メソッドを別スレッドで実行
		Thread staticThread = new Thread( MyThreadClass.StaticMethod );
		staticThread.Start();
 
		return 0;
	}
}

Thread.Start()では引数を与えることができます。
次のようにスレッドとして実行するメソッドが2つの引数を持つ場合には、2つの値を設定できます。

public class MyThreadClass {
	public static void StaticMethod(string text,int value) {
		Console.WriteLine("引数を使用してスレッドを実行中");
		Console.WriteLine("text引数={0}" , text);
		Console.WriteLine("value引数={0}" , value);
	}
 
	public void runThread() {
		Thread th = new Thread(StaticMethod);
		th.Start("スレッドから実行中",10);
	}
}

また、スレッドからスレッド呼び出し元へ値を返したい場合、コールバックを使用すると便利です。
コールバックとしてデリゲートを定義し、Thread.Start()を呼び出し時にデリゲートを渡すという単純な仕組みで実装しています。

public class MyThreadClass {
	delegate void procCallback(int value);
 
	public static void StaticMethod(string text,int value,procCallback callback) {
		Console.WriteLine("引数を使用してスレッドを実行中");
		Console.WriteLine("text引数={0}" , text);
		Console.WriteLine("value引数={0}" , value);
 
		if( callback != null ) {
			callback(1);
		}
	}
 
	public void runThread() {
		Thread th = new Thread(StaticMethod);
		th.Start("スレッドから実行中",10,new procCallback(ThreadCallbackMethod));
	}
 
	public static void ThreadCallbackMethod(int i) {
		Console.WriteLine("スレッドからのコールバック={0}" , i);
	}
}

スレッドの待機

Thread.Sleep()を使用すると現在のスレッドを任意の時間だけ処理を待機させることができます。

スレッドの中断要求

任意のスレッドのインスタンスからThread.Interrupt()を呼び出すと、対象のスレッドを中断させることができます。

Interruptが実行されたスレッドでは直ちにThreadInterruptedExceptionがスローされます。ただし、スレッドがどんな状態でもこのスローが呼び出されるわけではありません。 なぜなら、処理の途中でこの例外がスローしてしまうと、その処理の箇所から復帰することはできないためです。
そのため、スレッドがブロッキングされている箇所まで実行された後、ThreadInterruptedExceptionがスローされる事になっていることに注意が必要です。

class InterruptThreadTest {
	public void InstanceMethod() {
		try{
			Console.WriteLine("InstanceMethodからの呼び出し");
 
			Thread.Sleep(Timeout.Infinite); // スレッドのブロッキングが発生し、ここでInterruptが呼び出される。
		}catch(ThreadInterruptedException e) {
			Console.WriteLine("スレッドが中断されました");
		}
	}
}
 
public void main() {
	InterruptThreadTest obj = new InterruptThreadTest();
 
	Thread th = new Thread(obj.InstanceMethod);
	th.Start();
 
	Thread.Sleep(2000);
 
	th.Interrupt();
 
	th.Join();
}

上記のコードを実行すると

InstanceMethodからの呼び出し

(2秒間)

スレッドが中断されました

と表示されてアプリケーションは終了します。

スレッドの中止要求

任意のスレッドを中止させたい場合は、インスタンスからThread.Abort()を呼び出します。

スレッド側はInterruptと同じく例外をスローするのでそれをキャッチし、適切な終了処理を実行した後、スレッドを終了させます。
Abortの場合はThreadAbortException がスローされます。
スローされるタイミングはInterruptと同じくスレッドがブロックされている時に行われます。

Abort()を呼び出す側は、Abort()を呼び出してもその瞬間にスレッドが終了するわけではありません。
Abortはあくまでも中止要求であり、スレッドによってはスレッドが終了する際にリソースの解放など様々な後処理を行う必要があり、スレッドが完全に終了するまで時間がかかることがあります。

スレッドの呼び出し元でスレッドが停止するまで待機したい場合は、Abort()を呼び出した後にJoin()を呼び出しスレッドの終了を待機します。

UIスレッドとの関連

コントロールにコレクションをバインドし、そのコレクションをUIスレッドから使用とするとアプリケーションが強制終了してしまう。

この問題を回避するには、上記サイトにもあるようにコレクションの操作はDispatcherで行うのがよいそうです。

class DispatchObservableCollection<T> : ObservableCollection<T> {
		public DispatchObservableCollection() {
			InitializeEventDispatcher();
		}
		public DispatchObservableCollection(IEnumerable<T> collection)
			: base(collection) {
			InitializeEventDispatcher();
		}
		public DispatchObservableCollection(List<T> list)
			: base(list) {
			InitializeEventDispatcher();
		}
		private void InitializeEventDispatcher() {
			// インスタンスが作られた時のDispatcherを取得
			this.EventDispatcher = Dispatcher.CurrentDispatcher;
		}
 
		// CollectionChangedイベントを発行するときに使用するディスパッチャ
		public Dispatcher EventDispatcher {
			get;
			set;
		}
 
		private bool IsValidAccess() {
			return EventDispatcher == null || EventDispatcher.Thread == Thread.CurrentThread;
		}
 
		protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) {
			if (IsValidAccess()) {
				base.OnCollectionChanged(e);
			} else {
				// Dispatcher
				Action<NotifyCollectionChangedEventArgs> changed = OnCollectionChanged;
				this.EventDispatcher.Invoke(changed, e);
			}
		}
 
 
	}
  • http://d.hatena.ne.jp/okazuki/20100112/1263267397
  • http://msdn.microsoft.com/ja-jp/magazine/cc163328.aspx

タイマー使用方法

Timerクラスのインスタンスは保持しておく必要があります。

class MyClass {
	Timer timer;
 
	public MyClass() {
		TimerCallback cb = new TimerCallback(MyTimerThread);
 
		// 1000msec = 1sec間隔
		timer = new Timer(cb, null , 0, 1000);
	}
 
	public void MyTimerThread(object param) {
		Console.WriteLine(DateTime.Now);
	}
「スレッド」をウィキ内検索
LINE
シェア
Tweet

[Amazon商品]


プログラミング図書館・本館
記事メニュー

C#

  • 新機能
  • 言語文法
    • 型
    • 関数
    • クラス
    • 演算子
    • 構文
    • デリゲート
    • イベント
    • 例外処理
    • アトリビュート
    • 名前空間
    • ジェネリクス
  • リフレクション
  • LINQ

.NET Frameworks

  • 数値
  • 文字列
  • 日付時刻
  • オブジェクト
  • コレクション
  • ファイルシステム
  • スレッド
  • データテーブル
  • グラフィックス
  • デバッグ
    • ログ出力
    • ユニットテスト
  • ユーティリティ
  • ネットワーク
    • HTTP
  • デバイス
    • COMポート
  • EntityFrameworks
    • Code First Programming Model
  • デバイスドライバ
    • WinUSB

WPF

  • XAML
  • イベント
  • コマンド
  • スタイル
  • データバインディング
  • コンポーネント
  • グラフィックス
  • カスタムコンポーネント
    • 依存関係プロパティ

アプリケーション

  • 二重起動の防止
  • アンマネージドDLLの読み込み
  • 外部のアプリケーションを起動

VisualStudio

  • 拡張機能
  • カラー設定

ライブラリ

  • WPFToolkit
  • A Fast CSV Reader
  • AvalonDock

実装方法

  • ドラッグアンドドロップ
  • アプリケーション内のドラッグアンドドロップ
  • CSVからDataTable

minecraft

  • Bukkit
  • プラグイン
    • Permissions
    • SlowHealth
    • CookieMonster
    • iConomy
    • WorldGuard
    • Lockette
    • MyHome
    • BorderGuard

サイトについて

プロフィール/リンク/未分類

メモ/ゲーム/Stacks/Omoikane


更新履歴

取得中です。

ここを編集

記事メニュー2

読んでいる本


Effective C#

QLOOKアクセス解析

ここを編集

人気記事ランキング
  1. 構文
もっと見る
最近更新されたページ
  • 5033日前

    Bukkit
  • 5039日前

    トップページ
  • 5060日前

    メニュー
  • 5070日前

    WPF/グラフィックス
  • 5070日前

    .NET/グラフィックス
  • 5070日前

    .NET/グラフィックス/画像の書き込み
  • 5070日前

    .NET/グラフィックス/画像の読み込み
  • 5076日前

    .NET/コレクション
  • 5094日前

    .NET/WinUSB
  • 5129日前

    BorderGuardプラグイン
もっと見る
人気記事ランキング
  1. 構文
もっと見る
最近更新されたページ
  • 5033日前

    Bukkit
  • 5039日前

    トップページ
  • 5060日前

    メニュー
  • 5070日前

    WPF/グラフィックス
  • 5070日前

    .NET/グラフィックス
  • 5070日前

    .NET/グラフィックス/画像の書き込み
  • 5070日前

    .NET/グラフィックス/画像の読み込み
  • 5076日前

    .NET/コレクション
  • 5094日前

    .NET/WinUSB
  • 5129日前

    BorderGuardプラグイン
もっと見る
ウィキ募集バナー
新規Wikiランキング

最近作成されたWikiのアクセスランキングです。見るだけでなく加筆してみよう!

  1. 機動戦士ガンダム EXTREME VS.2 INFINITEBOOST wiki
  2. MadTown GTA (Beta) まとめウィキ
  3. R.E.P.O. 日本語解説Wiki
  4. シュガードール情報まとめウィキ
  5. ソードランページ @ 非公式wiki
  6. AviUtl2のWiki
  7. Dark War Survival攻略
  8. シミュグラ2Wiki(Simulation Of Grand2)GTARP
  9. 星飼いの詩@ ウィキ
  10. ヒカマーWiki
もっと見る
人気Wikiランキング

atwikiでよく見られているWikiのランキングです。新しい情報を発見してみよう!

  1. アニヲタWiki(仮)
  2. ストグラ まとめ @ウィキ
  3. 機動戦士ガンダム EXTREME VS.2 INFINITEBOOST wiki
  4. ゲームカタログ@Wiki ~名作からクソゲーまで~
  5. 初音ミク Wiki
  6. 発車メロディーwiki
  7. 検索してはいけない言葉 @ ウィキ
  8. Grand Theft Auto V(グランドセフトオート5)GTA5 & GTAオンライン 情報・攻略wiki
  9. 機動戦士ガンダム バトルオペレーション2攻略Wiki 3rd Season
  10. モンスター烈伝オレカバトル2@wiki
もっと見る
全体ページランキング

最近アクセスの多かったページランキングです。話題のページを見に行こう!

  1. 参加者一覧 - ストグラ まとめ @ウィキ
  2. 魔獣トゲイラ - バトルロイヤルR+α ファンフィクション(二次創作など)総合wiki
  3. 鬼レンチャン(レベル順) - 鬼レンチャンWiki
  4. 機体一覧 - 機動戦士ガンダム EXTREME VS.2 INFINITEBOOST wiki
  5. ドンキーコング バナンザ - アニヲタWiki(仮)
  6. チンポ画像収集場 - 検索してはいけない言葉 @ ウィキ
  7. 仕込みマシンガン/仕込み爆弾(遊戯王OCG) - アニヲタWiki(仮)
  8. ヤマダ電機の唄 - アニヲタWiki(仮)
  9. 危険度7 - 検索してはいけない言葉 @ ウィキ
  10. 千鳥の鬼レンチャン 挑戦者一覧 - 千鳥の鬼レンチャン サビだけカラオケデータベース
もっと見る

  • このWikiのTOPへ
  • 全ページ一覧
  • アットウィキTOP
  • 利用規約
  • プライバシーポリシー

2019 AtWiki, Inc.