blog

C#におけるFinallyのあまり一般的でない使い方

これは実はちょっとしたトリックで、Finallyに置かれたコードは、実行中のスレッドが他のスレッドによって中断されるのを防ぎます。これにより、コード実行の完全性が保証されます。...

Oct 12, 2014 · 2 min. read
シェア

.net BCL ソースコードを見ています。 その中で

System.Collections.Concurrent.ConcurrentQueue

で興味深いコードに出会いました。このコードはConcurrentQueueで書かれていることに注意してください。 これはロックフリーのキューの実装であることに注意してください。

try 
 { }  
 finally 
 {  
     newhigh = Interlocked.Increment(ref m_high);  
     if (newhigh <= SEGMENT_SIZE - 1)  
     {  
         m_array[newhigh] = value;  
         m_state[newhigh].m_value = true;  
     }  
     if (newhigh == SEGMENT_SIZE - 1)  
     {  
         Grow();  
     }  
 } 
面白いですか?このコードは空のTryブロックを使っています。そして、コードはすべてFinallyブロックに書かれています。これは何のためでしょうか?

これは実はちょっとしたトリックで、実行中のスレッドが Thread.Abort() や Thread.Interrupt() を呼び出して他のスレッドから実行中に割り込まれるのを、Finally に配置されたコードで防いでいるのです。これにより、コード実行の完全性が保証されます。

例えば、上記のコードをFinallyで実行しないとします。スレッドAが実行中に別のスレッドBがスレッドAのコードを呼び出した場合、後のコードが実行されない可能性があります。これでは、ConcurrentQueueが不完全になってしまいます。

そして、スレッドBスレッドAの実行がスレッドを呼び出す場合でも、最後にコードを置きます。

実際、この機能は.net framework 2.0で導入されました。.net1.1にはありませんでした。さらに、Tread.Abortはスレッド内の静的コンストラクタの実行を中断させることができます。

また、これと同じ機能を実現できると思います。

Read next

"るい教室 "はインテリジェントな教育クラウドを創造する

主な記事\n\n\nNECの「スマート教室」(東京\nNECの「類(るい)教室」は、タブレットPCとワイヤレスネットワークを活用し、日々の授業に先進的なIT技術を導入することで、教室内の交流を充実させ、教員の負担を軽減し、個に応じた授業や主体的な探究学習を実現するものです。現在、「Rui Classroom」はすでに東京都内でサービスを開始しています。

Oct 12, 2014 · 5 min read