|
.NET TIPS
スレッドの開始時にパラメータを渡すには?[2.0のみ、C#、VB]
デジタルアドバンテージ 遠藤 孝信
2006/04/07 |
|
|
.NET Frameworkのクラス・ライブラリでは、Threadクラス(System.Threading名前空間)を利用して特定のメソッドを別スレッドで実行させることができる。しかし.NET Framework 1.xでは、そのメソッド(以降、「スレッド・メソッド」と呼ぶ)はパラメータを取ることができなかった*。2.0ではスレッドの開始時にパラメータの指定が可能になっている。
* ThreadPool.QueueUserWorkItemメソッドやデリゲートのBeginInvokeメソッドを使えば、スレッドにパラメータを渡すことができる。ただしそのスレッドは.NET Frameworkが管理するスレッドプールのスレッドとなる。
|
フィールド経由でスレッド・メソッドにパラメータを渡す
.NET Framework 1.xでパラメータをスレッド・メソッドに渡すには、あらかじめクラスのフィールドにその値をセットしておくといった処理が必要である。以下のそのサンプル・プログラムを示す。
// thread.cs
using System;
using System.Threading;
public class WorkerClass {
// スレッドの実行に必要なデータ
string message;
public WorkerClass(string s) {
message = s;
}
// 別スレッドで実行されるメソッド
public void Worker() {
for (int i = 0; i < 5; i++) {
Console.WriteLine(message);
}
}
}
public class ThreadSample1 {
static void Main() {
WorkerClass wc = new WorkerClass("別のスレッド");
Thread t = new Thread(new ThreadStart(wc.Worker));
// デリゲートのインスタンス化は省略可
// Thread t = new Thread(wc.Worker);
t.Start();
Console.WriteLine("スレッドを開始しました");
// 出力例:
// スレッドを開始しました
// 別のスレッド
// 別のスレッド
// 別のスレッド
// 別のスレッド
// 別のスレッド
}
}
// コンパイル方法:csc thread.cs |
|
フィールド経由でメソッドにパラメータを渡すC#のサンプル・プログラム(thread.cs) |
|
' thread.vb
Imports System
Imports System.Threading
Public Class WorkerClass
' スレッドの実行に必要なデータ
Dim message As String
Public Sub New(ByVal s As String)
message = s
End Sub
' 別スレッドで実行されるメソッド
Public Sub Worker()
For i As Integer = 1 To 5
Console.WriteLine(message)
Next
End Sub
End Class
Public Class ThreadSample1
Shared Sub Main()
Dim wc As New WorkerClass("別のスレッド")
Dim t As New Thread(New ThreadStart(AddressOf wc.Worker))
' デリゲートのインスタンス化は省略可
' Dim t As New Thread(AddressOf wc.Worker)
t.Start()
Console.WriteLine("スレッドを開始しました")
' 出力例:
' スレッドを開始しました
' 別のスレッド
' 別のスレッド
' 別のスレッド
' 別のスレッド
' 別のスレッド
End Sub
End Class
' コンパイル方法:vbc thread.vb |
|
フィールド経由でメソッドにパラメータを渡すVBのサンプル・プログラム(thread.vb) |
|
ParameterizedThreadStartデリゲートを使ったスレッドの実行
.NET Framework 2.0では、スレッド・メソッドにobject型のパラメータを1つ持たせることができるようになっている。
この場合には、これまでのThreadStartデリゲートではなく、.NET Framework 2.0で新しく追加されたParameterizedThreadStartデリゲート(System.Threading名前空間)を経由してスレッド・メソッドを呼び出す。以下にParameterizedThreadStartデリゲートの定義を示す。
delegate void ParameterizedThreadStart(object obj)
|
Delegate Sub ParameterizedThreadStart(obj As Object)
|
|
ParameterizedThreadStartデリゲートの定義(上:C#、下:VB) |
スレッド・メソッドにパラメータとして渡す値は、ThreadクラスのStartメソッドのパラメータで指定する。
次のサンプル・プログラムは以上の方法を使って上記のサンプル・プログラムを書き換えたものだ。
// pthread.cs
using System;
using System.Threading;
public class ThreadSample2 {
// 別スレッドで実行されるメソッド
static void Worker(object o) {
// キャストが必要
string message = (string)o;
for (int i = 0; i < 5; i++) {
Console.WriteLine(message);
}
}
static void Main() {
Thread t = new Thread(new ParameterizedThreadStart(Worker));
// デリゲートのインスタンス化は省略可
// Thread t = new Thread(Worker);
t.Start("別のスレッド");
Console.WriteLine("スレッドを開始しました");
// 出力例:
// スレッドを開始しました
// 別のスレッド
// 別のスレッド
// 別のスレッド
// 別のスレッド
// 別のスレッド
}
}
// コンパイル方法:csc pthread.cs |
|
メソッドにパラメータを渡すC#のサンプル・プログラム(pthread.cs) |
|
' pthread.vb
Imports System
Imports System.Threading
Class ThreadSample2
Shared Sub worker(ByVal o As Object)
' キャストが必要
Dim message As String = CType(o, String)
For i As Integer = 1 To 5
Console.WriteLine(message)
Next
End Sub
Shared Sub Main()
Dim t As Thread = new Thread(new ParameterizedThreadStart(AddressOf worker))
' デリゲートのインスタンス化は省略可
' Dim t As New Thread(AddressOf worker)
t.Start("別のスレッド")
Console.WriteLine("スレッドを開始しました")
' 出力例:
' スレッドを開始しました
' 別のスレッド
' 別のスレッド
' 別のスレッド
' 別のスレッド
' 別のスレッド
End Sub
End Class
' コンパイル方法:vbc pthread.vb |
|
メソッドにパラメータを渡すVBのサンプル・プログラム(pthread.vb) |
|
コード内のコメントでも示しているが、C# 2.0やVisual Basic 2005ではデリゲートのインスタンス化(コンストラクタの呼び出し)を省略できる*。
* 実際には、スレッド・メソッドがパラメータを取らなければThreadStartデリゲートのコンストラクタの呼び出しがコンパイラにより自動生成され、object型のパラメータを1つ取る場合にはParameterizedThreadStartデリゲートのコンストラクタの呼び出しが自動生成される。
|
なお、スレッド・メソッドのパラメータはobject型であるため、上記のサンプル・プログラムのように、たいていの場合でパラメータの明示的なキャストが必要となる。つまりスレッド・メソッドのパラメータはタイプ・セーフではないため、実装に関しては注意が必要だ。
利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:クラス・ライブラリ 処理対象:スレッド
使用ライブラリ:Threadクラス(System.Threading名前空間)
使用ライブラリ:ParameterizedThreadStartデリゲート(System.Threading名前空間)
|
|
generated by
|
|
Insider.NET 記事ランキング
本日
月間