0

根本的に異なるタイプのジョブをキューに入れることができる UI があります。現時点では、ジョブをデータベースの適切なテーブルに格納することでこれを行います (Table-per-JobType)

次に、バックエンド プロセスがやって来てジョブを取得し、使用可能なワーカー (スレッド) があると仮定して、それを使用してジョブに適したメソッドを実行します。

擬似コードで:

While(Runnning) {
    While(Queue1.HasJobs && Workers.IdleCount > 0) {
        FirstIdleWorker.Execute(Queue1Method(Type1Job));
    }

    ...

    While(QueueN.HasJobs && Workers.IdleCount > 0) {
        FirstIdleWorker.Execute(QueueNMethod(TypeNJob));
    }
    //Wait for a job to complete or a polling timeout if queues are empty
}

(実際にはそれほど単純ではありませんが、作業が処理される順序を示しています)

ご覧のとおり、これは機能しますが、ジョブが追加された順序は考慮されていません。ジョブはアトミックであるため、これは問題ではありませんが、UI の観点からは面倒です。たとえば、ユーザー 1 は 20 個のジョブをキューに入れます。タイプ 2、次にユーザー 2 タイプ 1 の 1,000 ジョブをキューに入れます。ユーザー 1 は、(比較的) 迅速なジョブが処理される前に、ユーザー 2 のすべてのジョブが完了するまで待機する必要があります。

ジョブにはCreatedOnプロパティがあるため、順序を決定することは難しくありませんが、スパゲッティ コードではない厳密に型指定された方法で結合キューを実装するにはどうすればよいでしょうか?

.CreatedOn, .Queue1Id,.Queue2Idが付いた「GenericJob」オブジェクトを避けようとしてい.Queue3Idます。

FIFOは私が求めているものですが、厳密な要件ではありません.アイテムが永遠にぶつけられたくないだけです.

この種のパターンはありますか?そうでない場合は、誰かが私に良いチュートリアルを教えてもらえますか?

(ちなみに、これらのジョブは長時間実行される可能性があります。ジョブがキューから取り出されたら、実際にはバックグラウンドで TPL を使用してワーカーを管理していますが、自分よりもはるかに多くのジョブがあるため、キューを自分で管理する必要があります。一度にメモリにロードできます)

4

2 に答える 2

1

私が間違っている場合は、私を突いてください。この擬似コードがインターフェイスの抽象化をうまく説明していることを願っています。

インターフェイスは次のようになります。

enum JobTypes
{
    JobType1 = 0x01,
    JobType2 = 0x02,
    JobType3 = 0x03
}
interface IJob
{
    int ID { get; set; }
    JobTypes JobType { get; set; }
    DateTime Date { get; set; }
    bool Complete { get; set; }
    void Process(List<object> parameters);
}

各ジョブタイププロセッサは、このインターフェイスを実装し、ニーズに合わせてプロパティを変更および追加します。

class JobType1 : IJob
{
    public int ID { get; set; }
    public JobTypes JobType { get; set; }
    public DateTime Date { get; set; }
    public bool Complete { get; set; }
    public void Process(List<object> parameters)
    {
        throw new NotImplementedException();
    }
}

次に、ジョブタイプを1つのリストに混在させることができます。

List<IJob> joblist = new List<IJob>();

ラムダを使用して日付で並べ替えることもできます。

joblist.Sort((a, b) => DateTime.Compare(a.Date, b.Date));

未処理のジョブのリストを取得します(これらのビジーな処理をチェックしません*)

List<IJob> undone = joblist.Where(job => job.Complete == false) as List<IJob>;
于 2012-06-27T07:28:51.067 に答える
1

さまざまなリソースまたはリソースのレベルを必要とするジョブがあり、短いジョブが枯渇するのを避けたいため、完全な答えはおそらくジョブショップ スケジューリングのようなものです。これはやや複雑で、多少の読み取りが必要ですが、最終的には、1 つのキューからアドホックに複雑なスケジューリングを行うよりも作業が少なくて済みます。

ジョブ間に依存関係があるようには思えないので、より簡単な方法は、ユーザーごと、ジョブごとにキューを作成し、キューで加重ラウンドロビンを実行することです。(つまり、キュー Y からのジョブごとに、キュー X から 2 つのジョブを取得します。)

于 2012-07-18T14:05:16.177 に答える