2016-09-30 5 views
-2

ここに私の物語があります:私はwcfサービスを持っています。それは仕事の要求を受け取ります。各タスクはブロッキングキューに挿入されます。サーバーはこのキューからアイテムを定期的に取り出し、作業を行います(別のスレッドでは完全に非同期)。私の "Do"サービスでは、 "私"の仕事がいつ行われたかを知る必要があります。このように:ManualResetEventオブジェクトの配列

public bool Do(int input) 
    { 
     // 1. Add task to the BlockingCollection queue 
     // 2. Block this thread from returning and observe/wait til my task is finished 
     return true; 
    } 

ここに私の提案/ソリューションです:実行するタスクがあるよう

public bool Do(int input) 
    { 
     // 1. Create a ManualResetEvent object 
     // 2. Add this object to task 
     // 3. Add task to the BlockingCollection queue 
     // 4. Block this thread from returning - wait for ManualResetEvent object 
     return true; 
    } 

だから、できるだけ多くManualResetEventオブジェクトが存在します。私は文字通りシンクオブジェクトの配列を持っています。それは私の問題のための良い解決策ですか?

私の場合に使用する同期クラスがありますか?待っているとパルスのように?助けのための

おかげで、

私はタイトルのためにごめんなさい。私はタイトルでこの質問をする方法を知らなかった。

+0

各タスクのクラス状態オブジェクトを作成し、リストを作成します。状態とスレッドオブジェクトにtimeとidのようなプロパティを入れます。 – jdweng

答えて

2

あなたの計画は良いですが、私は仕事が完了するのを待っている専用のスレッドを縛らないことをお勧めします。 new ManualResetEvent(false)からnew SemephoreSlim(0,1)に切り替えると、を使用して、Doメソッドでasync/awaitを使用し、スレッドを解放して他の作業を行うことができます。セルフはあなたがSemaphoreSlimを変更することができます含まれているすべてのものを作成するには:(UPDATEこれは本当に代わりに、セマフォスリムのTaskCompletionSourceする必要がありますが、私は、この例では更新されません、下記の第二の部分を参照)

public async Task<bool> Do(int input) 
{ 
    using(var completion = new new SemephoreSlim(0,1)) 
    { 
     var job = new JobTask(input, completion); 
     _workQueue.Add(job); 
     await completion.WaitAsync().ConfigureAwait(false); 
     return job.ResultData; 
    } 
} 

private void ProcessingLoop() 
{ 
    foreach(var job in _workQueue.GetConsumingEnumerable()) 
    { 
     job.PerformWork(); //Inside PerformWork there is a _completion.Release(); call. 
    } 
} 

/TaskCompletionSourceを入力してジョブの中に入れ、ジョブ自体を返します。

​​
+0

@Scottに感謝します。なぜ、私は "非同期"を行うのですか? "Do"関数は、項目(単一の "int"を特定のもの)をキューに追加して、何も返しません。サーバーは定期的にバッチ処理を行い、「実行」します。 「キューに追加」した後、この特定の「id」が完了するまで待つ必要があります。 –

+0

私は 'Do'が必ず' true'を返すとは思っていません私は 'true'が行われた作業から来ていると思っていましたので、古い' ManualResetEvent'を使って '.WaitOne() 'Do'メソッドのコードです。返されたboolが仕事の仕事ではない場合は、単に 'void'を返します。私は答えをそのような例で更新します。ありがとう。 –

+0

私は 'return true'を追加して、wcfクライアントがジョブ(彼のid用)がサーバー上で実行されたときに応答を受け取ることができるようにしました。 –

関連する問題