簡體   English   中英

.NET 4中的任務調度程序設計(任務並行庫)

[英]Design for task scheduler in .NET 4 (Task Parallel Library)

我正在嘗試創建一個使用TPL以異步(和並行)方式執行計划任務的服務。

基本要求是,對於一堆不同的任務,每個任務都有自己的預定速率(一些要每秒執行一次,另外30秒,其他5分鍾等)要同時執行。 而且我不確定最好的解決方法,特別是考慮到ConcurrentBag(我考慮將其作為所有未來任務的持有者)不包含用於選擇需要執行的任務集合的方法。

這也意味着我不能使用WaitAny或WaitAll,因為這些短期運行的任務需要獨立完成並重新排隊。

我該怎么辦呢?

編輯:

好吧基本上我的設計是這樣的:

ScheduledTask,它是具有Scheduled DateTime屬性的Task的包裝器。 其中一堆存儲在ConcurrentBag中

一個控制器,它輪詢ConcurrentBag(當前只是一個while(true)循環,但可能是一個Timer或類似的東西),刪除任何已調度的,並且Start()是它們。

每個ScheduledTask都包含對ConcurrentBag的引用,並在完成時使用新的ScheduledTime將自身的新實例排入隊列。

到目前為止,這個設計似乎有效,但是每個Task都有一些東西,它們對ConcurrentBag的引用並不適合我。 任何設計意見或建議將不勝感激。

您是否考慮過使用RX的EventLoopScheduler?

Rx有許多不同的調度程序實現,但EventLoopScheduler聽起來像是適合你的。

要使用RX創建重復任務,您只需使用Observable.Interval(timespan, scheduler).Subscribe(action)

您無法使用concurrentbag,因為您需要刪除特定項目。

一種方法是讓每個任務看起來像

MyTask SomeAction() {
    DateTime now = DateTime.Now;
    DoSomeTask();
    return new MyTask { StartTime = now.AddMinutes(1), DoSomething = SomeAction }
}

調度程序看起來像

List<MyTask> tasklist = new List<MyTask>();

public void Scheduler() {
    for (;;)
        DateTime now = DateTime.Now;

        List<MyTask> tasksToRun;
        lock (taskList) 
            taskToRun = taskList.Where(x => x.StartTime <= now)
                                .ToList();

        var tasks = tasksToRun.Select(x => RunTask(x))
                              .ToArray();
        Thread.Sleep(1000);
    }
}

private Task<MyTask> RunTask(MyTask myTask) {
    lock (taskList)
        tasklist.Remove(myTask);

    return Task<MyTask>.Factory.StartNew(myTask.DoSomething())
                               .ContinueWith(t => {
                                                      if (t.Result != null)
                                                          lock (taskList)
                                                              taskList.Add(t.Result);
                                                  });
}

如果您不想自己動手,可以使用http://quartznet.sourceforge.net/

我使用線程池(不是TPL)為學校項目編寫了一個同步任務調度程序。 我從來沒有讓它變得異步; 您可以在單獨的后台線程上運行任務,並讓它執行回調委托。 在SourceForge上看到這里。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM