2

次の構文をよりエレガントに書く方法はありますか?

        Thread t0 = new Thread(new ParameterizedThreadStart(doWork));
        t0.Start('someVal');
        t0.Join();

        Thread t1 = new Thread(new ParameterizedThreadStart(doWork));
        t1.Start('someDiffVal');
        t1.Join();

20 の異なる値を渡したいと仮定すると、これを設定する最良の方法は何でしょうか? ループして最後に参加?

新しいスレッドがインスタンス化されていない場合 (以下のように)、スレッドを再開できないというエラーが発生します。例えば:

        Thread t1 = new Thread(new ParameterizedThreadStart(doWork));
        t1.Start('someVal');
        t1.Start('someDiffVal');
4

3 に答える 3

7

スレッドを開始してすぐに参加するのはなぜですか?

私は通常、次のようなことをします:

List<Thread> threads = new List<Thread>();

foreach (string item in items)
{
    string copy = item; // Important due to variable capture
    ThreadStart ts = () => DoWork(copy); // Strongly typed :)
    Thread t = new Thread(ts);
    t.Start();
    threads.Add(t);
}

foreach (Thread t in threads)
{
    t.Join();
}
于 2008-10-31T21:54:55.703 に答える
2

もう 1 つのオプション (.NET 4.0 または CTP を使用) は、Parallel.ForEach. ただし、まだ実行可能であるとは限りません。IDisposableまた、ここで使用されている良いブログ エントリ (誰が思い出せません) も見ました。

using(StartThread(arg1))
using(StartThread(arg2))
{
}

Dispose() メソッドは、生成されたスレッドで結合を行いました。つまり、ブロックを終了すると、すべてが完了します。かなりかわいい。

于 2008-10-31T22:00:58.733 に答える
0

パラメーターをクラスの一部にして、それらをプロパティにし、get/set メソッドでそれらをロックしてみませんか? 十分なパラメーターがある場合は、パラメーター オブジェクト自体をオブジェクトのプロパティにしてから、そのパラメーター ブロックをロックします。次のように:

class GonnaDoSomeThreading {
   private Object mBlockLock = new Object();
   private MyParameterBlock mBlock;
   public MyParameterBlock Block {
       get { 
            MyParameterBlock tmp;
            lock (mBlockLock){
                tmp = new MyParameterBlock(mBlock); //or some other cloning
            }
            return tmp; //use a tmp in order to make sure that modifications done
                        //do not modify the block directly, but that modifications must
                        //be 'committed' through the set function
       }
       set { lock (mBlockLock){ mBlock = value; } } 
   }
}

そして、すでに提案されているようにスレッドプールを実行します。そうすれば、データ アクセスをロックできるので、すべてのスレッドがロックを必要とする場合、それらは互いに待機することができます。

画像処理のような目的でこれを行っている場合 (多くの並列オブジェクトを一度に実行できる場合)、データを個別のチャンクに分割することをお勧めします。IE で、大きな画像に対して畳み込みを実行したいので、画像を 2 つに分割したいとします。次に、個別に作業する画像ブロックを作成する「Fragmentimage」関数を作成し、「MergeFragments」関数呼び出しですべての結果を結合できます。したがって、フラグメントは次のようになります。

class ThreadWorkFragment {
    <image type, like ushort>[] mDataArray;
    bool mDone;
}

スレッドがそのフラグメントにアクセスしたときに、最終的に「完了」と宣言し、ロックを解放し、次に、完了したブール値にフラグが立てられるのを待つだけの最終的なマージ関数を作成できます。そうすれば、設定が完了する前にスレッドの 1 つが停止し、そのスレッドが停止していることがわかっている場合は、そのスレッドが作業を完了していないこともわかり、エラー回復を行う必要があります。結合が発生するのを待つだけでは、スレッドがそのフラグメントを台無しにする可能性があります。

しかし、解決しようとしている問題に基づいて、実装する必要がある特定のアイデアがたくさんあります。

于 2008-10-31T22:15:13.557 に答える