質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

10493閲覧

C#のThreadLocalの機能がいまいちよくわかりません。

GiveAHand

総合スコア286

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

2クリップ

投稿2017/01/01 12:51

MCP取得の為に、勉強してます。

C#のクラスに、ThreadLocalというものがありますが、これがMIcrosoftのDeveloper Networkのサンプルや、解説を見ても、使い方がよくわからずに悩んでいます。

https://msdn.microsoft.com/ja-jp/library/dd642243(v=vs.110).aspx

C#

1using System; 2using System.Threading; 3using System.Threading.Tasks; 4 5class ThreadLocalDemo 6{ 7 8 // Demonstrates: 9 // ThreadLocal(T) constructor 10 // ThreadLocal(T).Value 11 // One usage of ThreadLocal(T) 12 static void Main() 13 { 14 // スレッドの名前を生成するスレッド変数 15 ThreadLocal<string> ThreadName = new ThreadLocal<string>(() => 16 { 17 return "Thread" + Thread.CurrentThread.ManagedThreadId; 18 }); 19 20 // 現在のスレッドのThreadNameを出力するアクション 21 Action action = () => 22 { 23 // Thread Name.Is Value Createdがtrueの場合、このスレッドで実行する 24 // する最初のアクションではないことを意味します。 25 bool repeat = ThreadName.IsValueCreated; 26 27 Console.WriteLine("ThreadName = {0} {1}", ThreadName.Value, repeat ? "(repeat)" : ""); 28 }; 29 30 // それらの8つを起動します。 4コア以下では、いくつかの繰り返しThreadNamesが表示されるはずです 31 Parallel.Invoke(action, action, action, action, action, action, action, action); 32 33 // 完了したら処分する 34 ThreadName.Dispose(); 35 } 36} 37

これは、上記のページに記載されているサンプルコードです。
コメントはGoogle翻訳で日本語にしました。

ここに出てくるThreadLocalは、何をするためのクラスなのでしょうか?

ラムダ式で、コンストラクタ内にカレントスレッドのIDを取得して返していますが、普通にThreadでやったらいけないのでしょうか?

そもそもこれが何を示す為のサンプルなのかがよくわかりません。

一体このサンプルは、何をしているのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

ここに出てくるThreadLocalは、何をするためのクラスなのでしょうか?

スレッドローカルな変数を宣言するためのクラスです。
普通に変数を宣言すると、どのスレッドからアクセスしても同じ変数が見えますが、スレッドローカルなな変数はスレッドごとに変数があるため、どのスレッドから参照するかによって値がことなります。
コンテキストを関数呼び出しの途中を乗り越えて渡すような場合に便利です。たとえば、 Web のアプリから呼び出される処理で何段もネストして呼び出されたサブルーチンの中で急にユーザIDとかが必要になったりすると、ネスト途上のすべてのサブルーチンの引数を追加して、順番にユーザIDを渡さなければなりません。これに対してリクエストの入り口でスレッドローカルな変数にユーザIDを設定しておき、必要なったところでこれを参照すれば、途中のサブルーチンはユーザIDのことを知らなくても済みます。

ラムダ式で、コンストラクタ内にカレントスレッドのIDを取得して返していますが、普通にThreadでやったらいけないのでしょうか?

スレッドIDがほしいだけであれば、それで実現できます。これは、あくまで例なので話を簡単にするためにスレッドIDを参照していますが、実際にはユーザIDなどそのときの処理内容に固有の値を保持します。

そもそもこれが何を示す為のサンプルなのかがよくわかりません。
一体このサンプルは、何をしているのでしょうか?

文字列型のスレッドローカル変数を作成できることと、それがオンデマンドに作成されることをデモしています。C# のスレッドローカル変数はスレッドが作成されるとすぐにメモリが確保されるわけではなく、参照すると初めてメモリが確保されるようにできています。スレッドによっては、その変数を参照しないものもあるような場合に性能負担を軽減できるということだと思います。

投稿2017/01/01 14:16

mit0223

総合スコア3401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

GiveAHand

2017/01/02 00:05

mito0223様 ものすごくわかりやすいご回答ありがとうございます! なるほど、そういう事なんですね! ありがとうございました! ところで蛇足ですが、mito0223様は、どうしてそんなにもお詳しいのですか?
mit0223

2017/01/02 06:57

ベストアンサーありがとうございます。実は C# はあまり詳しくありません。この業界に入ってあまりに長いので、OS、ミドルウェア、言語処理系の概念モデルだけは理解できるといったところです。
GiveAHand

2017/01/02 11:14

mit0223様 プロフィール見させて頂きました! 社長さんなんですね! 実は私もいい歳なんですが、いろいろあって今フリーでプログラマーですが、オブジェクト指向の考え方などがよくわからず、四苦八苦です。。。
guest

0

ThreadLocalは同じスレッドからでしか読み書きできない変数を作成するもの。
このサンプルはその動作を確認するためのもの。
こちらを読めばわかるかと。

投稿2017/01/01 14:15

turbgraphics200

総合スコア4267

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

GiveAHand

2017/01/02 00:07

turbgraphics200様 ご回答ありがとうございます! なるほど、よくわかりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問