0
public class JobRunner
{
    internal Timer Timer;
    internal readonly IEnumerable<YuartzJob> Jobs;

    public void Start()
    {
        this.Timer = new Timer(5000);
        this.Timer.Elapsed += Timer_Elapsed;
        this.Timer.Start();
    }

    public void Stop()
    {
        this.Timer.Stop();
    }

    internal void Timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        foreach (var job in Jobs)
        {
            MyActivator.RunJob(job);
        }
    }
}

public class MyActivator
{
    public static void RunJob(YuartzJob job)
    {
        var objectHandle = Activator.CreateInstance(job.AssemblyName, job.ClassName).Unwrap();
        var currentJob = (IJob)objectHandle;
        currentJob.Run();
    }
}

MyActivator.RunJob(job) を使用した場所をどうすればよいですか:

  1. ThreadPool を使用して MyActivator.RunJob を呼び出す必要がありますか?
  2. Threads を使用して MyActivator.RunJob を呼び出す必要がありますか?
  3. BackgroundWorker を使用して MyActivator.RunJob を呼び出す必要がありますか?
  4. 何もしなくてもこのままでいいの?
4

3 に答える 3

3

.NET 4をターゲットにしている場合、最も簡単な方法はタスクを使用することです。タスクは、ThreadPoolのスレッドを使用してメソッドを実行します。.NETランタイム(実際には、TaskScheduler)は、スレッドプールがあまりにも多くのタスクによって使い果たされていないことを確認します。

    foreach (var job in Jobs)
    {
        Task.Factory.StartNew(()=>MyActivator.RunJob(job));
    }

タスクを使用すると、ThreadPoolまたは独自のスレッドを使用する場合には不可能な、簡単なキャンセル、例外処理、およびチェーン化も可能になります。

以前のバージョンでは、最初にThreadPoolを検討し、ジョブが非常に多く長時間実行されているためにスレッドプールを使い果たすリスクがある場合にのみ、独自のスレッドを作成する必要があります。

    foreach (var job in Jobs)
    {
        ThreadPool.QueueUserWorkItem(o=>MyActivator.RunJob(job));
    }

Backgroundworkerは、.NET 4以降では廃止されたと見なされ、とにかく非常に粗い並列処理にのみ適しています。あなたの場合、ジョブごとに個別のワーカーを作成し、そのイベントをサブスクライブし、実行して、その後クリーンアップする必要があります。

于 2012-06-22T08:46:24.450 に答える
2

アイテムのコレクションを並行して効率的に処理したい場合、私の最初の選択肢は、まさにその目的のために作成されたものです: Parallel.ForEach().

内部的にはTasks を使用します。これは、 で実行されることを意味しますThreadPool。またTask、s を効率的に使用しようとするため、100 万個のアイテムを持つ のコレクションがある場合、100 万個Taskの s は作成されません。

于 2012-06-22T09:38:50.757 に答える
-1

.NET Framework は 4 つのタイマーを提供します。これらのうちの 2 つは、汎用のマルチスレッド タイマーです。

  • System.Threading.Timer
  • System.Timers.Timer

他の 2 つは、専用のシングルスレッド タイマーです。

  • System.Windows.Forms.Timer (Windows フォーム タイマー)
  • System.Windows.Threading.DispatcherTimer (WPF タイマー)

したがって、メソッドをマルチスレッド/並列で実行する場合は、最初の 2 つのうちの 1 つを選択する必要があります。

詳細については、こちらのサンプル ソース コードを参照してください。

于 2012-06-22T08:46:14.420 に答える