2012-03-27 10 views
1

私は、オブジェクト「コード」のリストを持っていますこれらのコードはすべての時間を実行されますので、このforeachのは、タイマーであるスレッドのリストを実行し

foreach(Code c in listCodes) 
{ 
    Thread tr = new Thread(delegate() { 
     Execute(c.CodeLine); 
    }); 
} 

が、私は同じコードをしても最初の実行場合多くの時間を実行していることを行うとき:私のような何かをしようとしましたコードが実行されて終了するのに5秒かかるとタイマーが500msであれば実行されます私は例のために5秒後にタイマーを無効にする場合は10回。

リスト内の各コードをスレッド内で実行するとは思えませんでしたが、実行後に終了した場合にのみ、コード0(例)のスレッドを実行します。

ありがとうございます。

+1

かなり醜いですタイマー。表示されているとおり、理由はありません。スレッド内でループ処理を行い、ManualResetEventを使用してループを停止することもできます。 –

答えて

4

System.Threading.Monitor.TryEnterは仕事のために完全である:それは何

foreach(Code c in listCodes) { 
    Code a = c; 

    new Thread(delegate() { 
     if(Monitor.TryEnter(a)) { 
      Execute(a.CodeLine); 
      Monitor.Exit(a); 
     } 
    }) { IsBackground = true }.Start(); 
} 

Codeオブジェクトの排他ロックを取得しようとしています。できない場合(つまり、Codeが既に実行中の場合)、何も起こりません。それ以外の場合は、ロックが取得され、実行が完了すると解放されます。

+0

スレッドが実行を開始したときに排他ロックを解除しませんか?コントロールはExecute()の直後に呼び出し元に返されます。 –

+0

@EricJ .:いいえ、ロックコードはループ内ではなくスレッド内にあります。 – Ryan

+0

LOLはそれを逃した。以前は明示的にスレッドを作成していたので、TPLに慣れました。 –

0

Threadが完了するまで実際に待つ必要があります。 Join

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

foreach(Code c in listCodes) 
{ 
    Thread tr = new Thread(delegate() { 
     Execute(c.CodeLine); 
    }); 
    threads.Add(tr); 
} 

foreach(Thread tr in threads) 
{ 
    tr.Join(); 
} 

これはすべて外部タイマーの内側にあります。

+1

他のすべてのスレッドが完了するまでメインスレッドをブロックします。ブロックすることができるスレッドでコードスレッドを実行する必要があります。 –

1

私はThreadのように非効率的だと思いますが、代わりにTaskを使用してください。 C#5で

、私はこのようにそれを行うだろう:

private static async Task RunCode(Code code, TimeSpan delay) 
{ 
    while (!Stopped) 
    { 
     var delayTask = Task.Delay(delay); 

     Execute(code.CodeLine); 

     await delayTask; 
    } 
} 

そして(すなわちないタイマーで)一度起動します

foreach (Code c in listCodes) 
{ 
    Task.Run(() => RunCode(c, TimeSpan.FromMilliseconds(1000))); 
} 
関連する問題