Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C语言中调度一系列不规则间隔的任务#_C#_Multithreading_Timer_Scheduled Tasks - Fatal编程技术网

C# 在C语言中调度一系列不规则间隔的任务#

C# 在C语言中调度一系列不规则间隔的任务#,c#,multithreading,timer,scheduled-tasks,C#,Multithreading,Timer,Scheduled Tasks,假设我有一个文件,其中列出了要执行的任务以及执行这些任务的时间间隔,如: Task_A 2 seconds Task_B 10 seconds Task_C 1 minute Task_A ... 所以当这个列表被读入,然后被允许执行时,它会执行任务A,等待2秒,执行任务B,等待10秒,依此类推 我该怎么做?我对System.threading.timer进行了一些研究,但这似乎是一个重复执行任务的设定时间间隔,但在本例中,我正在读取一个文件,其中列出了要执行的操作以及在执行之前的多长时间(不

假设我有一个文件,其中列出了要执行的任务以及执行这些任务的时间间隔,如:

Task_A
2 seconds
Task_B
10 seconds
Task_C
1 minute
Task_A
...
所以当这个列表被读入,然后被允许执行时,它会执行任务A,等待2秒,执行任务B,等待10秒,依此类推

我该怎么做?我对System.threading.timer进行了一些研究,但这似乎是一个重复执行任务的设定时间间隔,但在本例中,我正在读取一个文件,其中列出了要执行的操作以及在执行之前的多长时间(不同的语法,但此语法使解释更容易)

这个函数在backgroundworker中,所以我可以执行Thread.Sleep(Timespan),并且对我的GUI没有任何问题,但这感觉就像用铁砧敲钉子一样。作为System.threading.timer的OnTimedEvent的一部分,我也可以使用它来改变自己的时间间隔,但我不确定这是否是一个好的做法,或者它是否会工作


执行此操作的最佳方法是什么?

System.Timers.Timer会有所帮助

首先,任务的基本类,您可能通过数据库或其他方式拥有它

public class Task
{
    public Task()
    { 

    }

    public Task(String tName, Int32 iInterval, Int16 iPriority)
    {
        this.taskName = tName;
        this.nextInterval = iInterval;
        this.priority = iPriority;
    }

    private String taskName = String.Empty;

    public String TaskName
    {
        get
        {
            return this.taskName;
        }
        set
        {
            this.taskName = value;
        }
    }

    private Int32 nextInterval = 1;

    public Int32 NextInterval
    {
        get
        {
            return this.nextInterval;
        }
        set
        {
            this.nextInterval = value;
        }
    }

    private Int16 priority = 1;

    public Int16 Priority
    {
        get
        {
            return this.priority;
        }
        set
        {
            this.priority = value;
        }
    }
}
然后是如何执行部分

public class ExecuteTasks
{
    private System.Timers.Timer myTimer = new System.Timers.Timer();
    private Int32 TaskIndex = 0;
    private Int32 TaskCount = 3;

    protected void StartExecution()
    {
        myTimer.Interval = 1;
        myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
        myTimer.Start();
    }

    void myTimer_Elapsed(object sender, EventArgs e)
    {
        myTimer.Stop();

        if (TaskIndex < TaskCount)
        {             
            Task aTask = GetTasks()[TaskIndex++];
            StartTask(aTask.TaskName);
            SetNextTaskTimer(aTask.NextInterval);
        }
    }

    void SetNextTaskTimer(Int32 Seconds)
    {   
        myTimer.Interval = (Seconds * 1000) - DateTime.Now.Millisecond - 1;//Interval is set in miliseconds
        myTimer.Start();
    }

    void StartTask(String TaskName)
    {
        ProcessStartInfo objStartInfo = new ProcessStartInfo();
        objStartInfo.FileName = TaskName;

        Process objProcess = new Process();
        objProcess.StartInfo = objStartInfo;
        objProcess.Start();
    }

    //You will be reading your tasks from your database or a file
    List<Task> GetTasks()
    {
        List<Task> lstTasks = new List<Task>();

        lstTasks.Add(new Task("Task A", 2, 1));
        lstTasks.Add(new Task("Task B", 10, 2));
        lstTasks.Add(new Task("Task C", 60, 3));

        return lstTasks.OrderBy(le => le.Priority).ToList();
    }
}
而不仅仅是任务名称

最后触发执行部分

ExecuteTasks iExecute = new ExecuteTasks();
iExecute.StartExecution();
对于多线程,您可以使用锁机制、监视器类等,以适合您的需要为准。i、 e

lock(obj)//lock on an object
{
    ExecuteTasks iExecute = new ExecuteTasks();
    iExecute.StartExecution();
}

使用BackgroundWorker/Thread.Sleep有什么问题?此外,任务B是在前一个任务完成后2秒启动,还是在其启动后2秒启动?+1至@muratgu;我还建议您可以通过每次启动计时器时重置间隔来使用计时器。对于Thread.Sleep注释,一个原因是我不确定是否是忙等待。其次,在这个实际的程序中,Task_A可能在一段时间内甚至几个小时后都不会真正启动,我计划提交给一些调度器:在12:00:00运行Task_A,在12:00:02运行Task_B,等等。这些日期时间将根据调度文件中列出的延迟来确定。对于开始或结束问题,在这种情况下,它实际上并不重要,但是假设任务B在任务A开始后2秒开始。任务本身只需要几毫秒,延迟通常会很高(如分钟或小时),但可能会低至250毫秒。对于250毫秒的任务,它们的计时并不关键,因此以275毫秒甚至500毫秒的速度运行不会破坏交易。
lock(obj)//lock on an object
{
    ExecuteTasks iExecute = new ExecuteTasks();
    iExecute.StartExecution();
}