スレッドセーフな配列(ArrayList,HashTable,Queue,Stack)を作成する。(SyncRoot,Synchronized)非ジェネリック版。

基本的に配列の操作はスレッドセーフではないので(あるスレッドが配列に追加・削除している途中で、別スレッドでFor Eachしたら正しく列挙できない)マルチスレッドで配列のデータを操作する場合は、同時に実行されないようにロックする必要があります。

■lockステートメントによるスレッドセーフ化


using System;
using System.Collections;

namespace ThreadSafeCollection
{
class Program
{
static void Main(string[] args)
{
Queue SafeQueue = new Queue();

lock (SafeQueue.SyncRoot)
{
SafeQueue.Enqueue("AddObject");

}
}
}
}

ArrayList,HashTable,Queue,Stackクラスにはそれぞれロック用のオブジェクトをSyncRootプロパティに格納しています。このオブジェクトを使ってロックを行ってから、処理を実行するとスレッドセーフにすることが出来ます。但し、配列を操作するすべての箇所でlockステートメントによる記述を行う必要があります。

■Synchronizedスタティックメソッドによるスレッドセーフ化


using System;
using System.Collections;

namespace ThreadSafeCollection
{
class Program
{
static void Main(string[] args)
{

Queue SafeQueue = new Queue();
SafeQueue = Queue.Synchronized(SafeQueue);

SafeQueue.Enqueue("AddObject");

}
}
}

Synchronizedスタティックメソッドを使うとスレッドセーフな配列に変換することができます。これを行うことで配列に対する処理がスレッドセーフになります。個別にlockステートメントによる記述をする必要はなくなります。

*追記(2009-01-07)
gsf_zero1さんからトラックバックをいただきました。
Synchronizedしたコレクションの操作でスレッドセーフ化される範囲についての記事です。
Synchronizedでは、イテレータ(For Each)の処理はスレッドセーフにならないので要注意との事です。大事なポイントです。

[C#] Synchronizedしたコレクションの操作 (Collection, Queue, Synchronized, IsSynchronized, lock, CopyTo)
http://d.hatena.ne.jp/gsf_zero1/20100107/p2