<?xml version="1.0" encoding="UTF-8" ?><rdf:RDF 
  xmlns="http://purl.org/rss/1.0/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xml:lang="ja">
  <channel rdf:about="http://w.atwiki.jp/sawawra_bunkakai/">
    <title>sawawra_bunkakai @ ウィキ</title>
    <link>http://w.atwiki.jp/sawawra_bunkakai/</link>
    <atom:link href="https://w.atwiki.jp/sawawra_bunkakai/rss10.xml" rel="self" type="application/rss+xml" />
    <atom:link rel="hub" href="https://pubsubhubbub.appspot.com" />
    <description>sawawra_bunkakai @ ウィキ</description>

    <dc:language>ja</dc:language>
    <dc:date>2009-10-31T12:11:18+09:00</dc:date>
    <utime>1256958678</utime>

    <items>
      <rdf:Seq>
                <rdf:li rdf:resource="https://w.atwiki.jp/sawawra_bunkakai/pages/33.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/sawawra_bunkakai/pages/21.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/sawawra_bunkakai/pages/32.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/sawawra_bunkakai/pages/28.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/sawawra_bunkakai/pages/31.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/sawawra_bunkakai/pages/30.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/sawawra_bunkakai/pages/29.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/sawawra_bunkakai/pages/26.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/sawawra_bunkakai/pages/27.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/sawawra_bunkakai/pages/2.html" />
              </rdf:Seq>
    </items>
	
		
    
  </channel>
    <item rdf:about="https://w.atwiki.jp/sawawra_bunkakai/pages/33.html">
    <title>スレッドの強制終了</title>
    <link>https://w.atwiki.jp/sawawra_bunkakai/pages/33.html</link>
    <description>
      -強制終了はThread.Abort()メソッド
-強制終了させられたスレッドは、ThreadAbortException例外を投げる。

#highlight(csharp){{ 
…
    // ワーカスレッド用関数
    private void WorkerThread()
    {
        int cnt = 0;
        try
        {
            while (true)
            {
                cnt++;
                System.Threading.Thread.Sleep(50);
            }
        }
        catch (ThreadAbortException)
        {
            MessageBox.Show(&quot;スレッドが停止した&quot;, &quot;メッセージ&quot;);
        }
    }

    // メインスレッド用関数
    static void Main(string[] args)
    {
        // スレッドを開始する。
        Thread subThread = new Thread(new ThreadStart(WorkerThread));
        subThread.Start();

        // スリープ（Main関数を少し停止）
        Thread.Sleep(1000);

        // ★☆ ワーカスレッドの強制終了
        subThread.Abort();
    }
…
}}    </description>
    <dc:date>2009-10-31T12:11:18+09:00</dc:date>
    <utime>1256958678</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/sawawra_bunkakai/pages/21.html">
    <title>マルチスレッド</title>
    <link>https://w.atwiki.jp/sawawra_bunkakai/pages/21.html</link>
    <description>
      ここは、マルチスレッド調査チームのトップページです。

.NET[[フレームワーク]]を利用した、マルチスレッドプログラミングの基礎をまとめています。

**トピックス
+[[シンプルなスレッド]]
+[[フォアグラウンド／バックグラウンド]]
+[[スレッド同士の情報受け渡し]]
+[[GUIの別スレッドからの更新]]
+[[ドラッグ＆ドロップで別スレッド : BackgroundWorkerクラス (1)]]
+[[ドラッグ＆ドロップで別スレッド : BackgroundWorkerクラス (2)]]
+[[スレッドの中断と再開]]
+[[スレッドの強制終了]]
+スレッド間でウィンドウメッセージ送受信


***参考資料
-[[.NETフレームワークのためのC#システムプログラミング&gt;http://www.amazon.co.jp/NET%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEC-%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E2%80%95Visual-Studio2008%E5%AF%BE%E5%BF%9C-%E5%8C%97%E5%B1%B1-%E6%B4%8B%E5%B9%B8/dp/4877831924/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1253025594&amp;sr=8-1]]
--北山洋幸 著／カットシステム
-[[++C++&gt;http://ufcpp.net/index.html]]

(2009.08.03 ㊥)
-スケジュール
--調査（2～3か月）
--サンプルの作成（2～3か月）
    * 調査対象は、マルチスレッドのパターンやスレッド間通信の手法
    * 調査結果は、レポートとサンプルでまとめる    </description>
    <dc:date>2009-10-31T12:07:37+09:00</dc:date>
    <utime>1256958457</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/sawawra_bunkakai/pages/32.html">
    <title>スレッドの中断と再開</title>
    <link>https://w.atwiki.jp/sawawra_bunkakai/pages/32.html</link>
    <description>
      -中断はThread.Suspend()メソッド，再開はThread.Suspend()
-中断中に資源をつかみっぱなしにならないように注意。

#highlight(csharp){{ 
…
    // ワーカスレッド用関数
    private static void WorkerThread()
    {
        while(true)
        {
            // スリープ（WorkerThread関数を少し停止）
            Thread.Sleep(1000);

            Console.WriteLine(&quot;ワーカスレッド動作中！！&quot;);
        }
    }

    // メインスレッド用関数
    static void Main(string[] args)
    {
        // スレッドを開始する。
        Thread subThread = new Thread(new ThreadStart(WorkerThread));
        subThread.Start();

        // スリープ（Main関数を少し停止）
        Thread.Sleep(1000);

        // ★☆ ワーカスレッドの中断
        subThread.Suspend();

        // スリープ（Main関数を少し停止）
        Thread.Sleep1000();

        // ★☆ ワーカスレッドの再開
        subThread.Resume();
    }
…
}}    </description>
    <dc:date>2009-10-24T13:48:06+09:00</dc:date>
    <utime>1256359686</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/sawawra_bunkakai/pages/28.html">
    <title>スレッド同士の情報受け渡し</title>
    <link>https://w.atwiki.jp/sawawra_bunkakai/pages/28.html</link>
    <description>
      -スレッド間の値の受け渡しには以下のような方法が考えられる。
--ThreadクラスのStart()前にプロパティを設定（スレッド起動時のみ）
--共通で参照できるフィールドを使用。キューなどを併用してもよい（基本的に同クラス内の別スレッド間の場合）
--イベントを使用（別クラスの別スレッド間）
--コールバックを使用（別クラスの別スレッド間）

-カプセル化を一番促進できるのはイベントを使用するパターンだと思う。（コード例は、[[ドラッグ＆ドロップで別スレッド : BackgroundWorkerクラス (2)]]にて記述）
-下記コードの例ではコールバックを使用している。
 
#highlight(csharp){{
// スレッドクラス
public class subThread
{
    private string msg;
    private int wait;
    private getCompleteCode callback;

    // コンストラクタ
    public subThread(string msg, int wait, getCompleteCode callbackProcDelegate)
    {
        this.msg = msg;
        this.wait = wait;

        // ★☆コールバック関数をメンバのデリゲートに設定★☆
        callback = callbackProcDelegate;
    }

    public void wThread()
    {
        Console.WriteLine(this.msg);
        Thread.Sleep(this.wait);        // 待つ        

        // ★☆コールバック関数をデリゲートを使用してコール★☆
        callback(wait + 10);
    }
}

// デリゲートの宣言：完了コードの取得
public delegate void getCompleteCode(int completeCode);

// メインスレッド
class Program
{
    static void Main(string[] args)
    {
        Thread thread;

        // オブジェクトの作成
        // ★☆第３引数で、コールバック用のメソッドをデリゲートで指定★☆
        subThread sub = new subThread(&quot;ワーカスレッド開始.&quot;, 1000,
                                            new getCompleteCode(completeCode));

        // スレッドを作成
        thread = new Thread(new ThreadStart(sub.wThread));

        // スレッドを開始する
        thread.Start();
    }

    // コールバックメソッド
    public static void completeCode(int completeCode)
    {
        Console.WriteLine(&quot;完了コード={0}.&quot;, completeCode);
    }
}
}}    </description>
    <dc:date>2009-10-24T13:35:36+09:00</dc:date>
    <utime>1256358936</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/sawawra_bunkakai/pages/31.html">
    <title>ドラッグ＆ドロップで別スレッド : BackgroundWorkerクラス (2)</title>
    <link>https://w.atwiki.jp/sawawra_bunkakai/pages/31.html</link>
    <description>
      -BackgroudWorkerクラスでは、以下のイベントにメインスレッド側クラスのメソッドを登録することで、ワーカスレッドでのイベント発生を知ることができる。
--ProgressChanged：実行状態の更新
--RunWorkerCompleted：実行の終了
-ワーカスレッド側でProgressChangedイベントを発生させるには、BackgroundWorker.ReportProgress()メソッドを呼べばよい。
-RunWorkerCompletedイベントは、ワーカスレッドが終了すれば勝手に発生する。

#ref(BackgroundWorker3.png)

-CancellationPendingプロパティを使用すると、ワーカスレッドの中断を実現できる。（でも、ワーカスレッド側でCancellationPendingプロパティの定期的なチェック処理を書かねばならず、少しショボい気がする）


#highlight(csharp){{ 
…
  private void BW_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
  {
    // イベントを送信してきたインスタンスを取得
    BackgroundWorker wtBW = (BackgroundWorker)sender;

    while (true)
    {
      ++gCount;

      // ★☆ProgressChangedイベントを発生させ、登録されているメソッドを発生させる
      wtBW.ReportProgress(0);

      Thread.Sleep(500);

      // ★☆CancellationPendingをチェックして、trueだったらワーカスレッドを終了させる
      if (wtBW.CancellationPending)
      {
        return;
      }
    }
  }
…
}}

-スレッド間での値の受け渡しは、BackgroundWorkerクラスと同様にイベントを使用するのがよさそう。
-同じクラス内の別スレッドの場合は、共通フィールドを使うしかない。    </description>
    <dc:date>2009-10-24T13:17:10+09:00</dc:date>
    <utime>1256357830</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/sawawra_bunkakai/pages/30.html">
    <title>ドラッグ＆ドロップで別スレッド : BackgroundWorkerクラス (1)</title>
    <link>https://w.atwiki.jp/sawawra_bunkakai/pages/30.html</link>
    <description>
      -BackgroundWorkerクラスを使えば、コードを書かずに別スレッドを立てられる。
-マルチスレッド処理を組み込みたいWindowsフォームやコントロールに、ツールボックスにある「BackgroundWorker」をドロップすれば、別スレッドオブジェクトの出来上がり。

#ref(BackgroundWorker1.png)

-ドロップしたBackgroundWorkerの名前.RunWorkerAsync()のコールだけで、ワーカスレッドが開始される。
-RunWorkerAsync()のコールで開始される処理内容は、DoWorkプロパティにメソッド名を入れればよい。（別スレッドでbw_DoWork()メソッドを起動させたいときは、以下の図のようにすればよい）

#ref(BackgroundWorker2.png)


#highlight(csharp){{ 
…
    // 「開始」ボタン
    private void button1_Click(object sender, EventArgs e)
    {
        // ★☆ BackgroundWorkerで実装している別スレッドの開始。
        bw.RunWorkerAsync();
    }

    // ★☆ 別スレッドで動作してほしい処理を記述する。
    // ★☆ 事前に&quot;bw_DoWork&quot;というメソッド名をプロパティウィンドウで指定する必要する必要あり。
    private void bw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        for (loop = 0; loop &lt; 3; loop++)
        {
            MessageBox.Show(&quot;別スレッドだがや&quot;);
            Thread.Sleep(1000);
        }
    }
…
}}    </description>
    <dc:date>2009-10-24T13:13:44+09:00</dc:date>
    <utime>1256357624</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/sawawra_bunkakai/pages/29.html">
    <title>GUIの別スレッドからの更新</title>
    <link>https://w.atwiki.jp/sawawra_bunkakai/pages/29.html</link>
    <description>
      -GUIコントロール（TextBox等）は、基本的に同じスレッドからしかプロパティにアクセスできない。
-別スレッドからのアクセスは、Control.Invoke()を使ってデリゲート越しに実現させる。（TextBoxクラスはControlクラスの派生クラス）

#highlight(csharp){{ 
…
    // デリゲートの宣言
    private delegate void deleDispCount(UInt32 inCounter);

    // デリゲート
    private void subThread(UInt32 inCounter)
    {
        // デリゲートの作成
        deleDispCount dCount = new deleDispCount(ReCount);

        // ★☆ Control.Invokeメソッドを利用することで、コントロールのプロパティを更新可能。
        // ★☆ Control.Invokeメソッドはデリゲートを引数に持つので、
        // ★☆ デリゲートの中にコントロールのプロパティを更新する処理（メソッド）を入れる。
        textBox1.Invoke(dCount, new object[] { inCounter });
    }

    // デリゲートで呼ばれるメソッド
    void ReCount(UInt32 cnt)
    {
        // TextBoxコントロールのプロパティの更新処理
        textBox1.Text = cnt.ToString();
    }
…
}}

-コントロールは総じてスレッドセーフでないので、別スレッドからの更新にはこのような特別な仕掛けが必要。
-MSDNをみると、.NET Frameworkの各クラスのドキュメント内には、そのクラスがスレッドセーフか否かが書いてある。    </description>
    <dc:date>2009-09-19T22:39:33+09:00</dc:date>
    <utime>1253367573</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/sawawra_bunkakai/pages/26.html">
    <title>フォアグラウンド／バックグラウンド</title>
    <link>https://w.atwiki.jp/sawawra_bunkakai/pages/26.html</link>
    <description>
      -ThreadインスタンスのIsBackgroundプロパティにtrueを設定すると、そのスレッドは「バックグラウンドスレッド」になる。（サブのスレッドを開始する側のスレッドは「フォアグラウンドスレッド」）
-バックグラウンドスレッドは、フォアグラウンドスレッドが消えると自動的に終了する。
-メインスレッドが消えると同時に勝手に終了してほしいスレッドは、バックグラウンドに指定するとよい。

#highlight(csharp){{
…
    // サブスレッド用関数
    private static void threadSub()
    {
        Console.WriteLine(&quot;ワーカスレッド開始.&quot;);
    }

    static void Main(string[] args)
    {
        // スレッドを作成
        Thread thread = new Thread(new ThreadStart(threadSub));

        // ★☆ バックグラウンドスレッドに指定。
        // ★☆ これによって、Main()メソッドが終了と同時にサブスレッドも終了することになる。
        // ★☆ この例だとあまり意味はないか…
        thread.IsBackground = true;

        // スレッドを開始する
        thread.Start();
    }
…
}}    </description>
    <dc:date>2009-09-19T22:38:55+09:00</dc:date>
    <utime>1253367535</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/sawawra_bunkakai/pages/27.html">
    <title>シンプルなスレッド</title>
    <link>https://w.atwiki.jp/sawawra_bunkakai/pages/27.html</link>
    <description>
      -Threadクラスを使用する。
-Threadクラスのコンストラクタには、サブスレッドで動作してほしい関数をデリゲートで渡す。
-インスタンス生成後にThread.Start()をコールすると、サブスレッドが動作する。

#highlight(csharp){{ 
…
    // サブスレッド用関数
    private static void threadSub()
    {
        Console.WriteLine(&quot;ワーカスレッド開始.&quot;);
    }

    // メインスレッド用関数
    static void Main(string[] args)
    {
        // ★☆ スレッドを作成。
        // ★☆ Threadクラスのコンストラクタの引数は、ThreadStart型のデリゲート。
        Thread thread = new Thread(new ThreadStart(threadSub));

        // ★☆ スレッドを開始する。
        thread.Start();
    }
…
}}

-ちなみに、Javaで同じことを行うには、Threadクラス（に相当するクラスやインターフェイス）を継承したクラスを作る必要があるようだ。
-ただ別スレッドで動かしたい処理があるだけの理由で、クラス単位の実装が必要になるとは。。。    </description>
    <dc:date>2009-09-19T22:38:13+09:00</dc:date>
    <utime>1253367493</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/sawawra_bunkakai/pages/2.html">
    <title>メニュー</title>
    <link>https://w.atwiki.jp/sawawra_bunkakai/pages/2.html</link>
    <description>
      **メニュー
-[[トップページ]]
-[[メニュー]]

-[[テーマ決め]]
-[[活動・発表スケジュール]]

-[[フレームワーク]]
-[[オブジェクト指向]]
-[[VBA]]
-[[C#]]
-[[マルチスレッド]]


-[[雑談用]]

----

**リンク
-[[@wiki&gt;&gt;http://atwiki.jp]]
-[[@wikiご利用ガイド&gt;&gt;http://atwiki.jp/guide/]]

-[[プラグイン紹介&gt;プラグイン]]
-[[まとめサイト作成支援ツール]]

// リンクを張るには &quot;[&quot; 2つで文字列を括ります。
// &quot;&gt;&quot; の左側に文字、右側にURLを記述するとリンクになります


//**更新履歴
//#recent(20)

&amp;link_editmenu(text=ここを編集)    </description>
    <dc:date>2009-08-02T11:45:38+09:00</dc:date>
    <utime>1249181138</utime>
  </item>
  </rdf:RDF>
