【问题标题】:Start several functions at the same time in every x seconds?每 x 秒同时启动多个功能?
【发布时间】:2012-08-17 15:58:39
【问题描述】:

我知道如何在 x 秒内启动一个函数,类似于 this:

private Timer timer1; 
public void InitTimer()
{
    timer1 = new Timer();
    timer1.Tick += new EventHandler(timer1_Tick);
    timer1.Interval = 2000; // in miliseconds
    timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
    function1();
    function2();
    function3();
}

这里的问题:函数不能同时运行。 Function2 只能在 Function1 完成后运行。但我希望它们同时运行。这就是为什么我可以这样做:

private void timer1_Tick(object sender, EventArgs e)
{
   Parallel.Invoke(
     () => Function1(),
     () => Function2(),
     () => Function3()
   );
}

这是在 c# 中最聪明的方法吗?我对Parallel.Invoke 的不理解:如果我的计时器设置为 5 秒并且在 5 秒后功能 1、2 和 3 没有完成但我再次调用它们会怎样。我是否在 new 线程中启动这些功能?是否有一些调用 x-threads 运行 function1() (同时)?想知道这真的很健康。

如果有人想获得更多信息:function1 只是用来将文件 x 从文件夹 a 复制到 b,function2 只是在那里读取文件夹 b 中的所有文件并保存信息,function3 是只有在那里检查连接,如果有连接,则将适当的文件发送给某人。

对代码有什么建议吗?谢谢你

【问题讨论】:

  • 并行执行与串行执行相反。你的第一个例子有什么问题?
  • 根据您的最后一段,听起来您不希望它们并行运行,因为听起来 3 取决于 2 识别文件,而 2 取决于 1 移动文件。这准确吗?
  • 我认为最好并行处理。如果 function3 已经可以将文件发送给某人但由于 function1 仍在做某事而导致 function3 无法运行怎么办?或者说,也许有 100000 个文件供 function1 复制。现在 function2 必须等待,即使有 5000 个文件为下一个任务做好准备,直到 function1 处理完这 100000 个文件。

标签: c# .net multithreading


【解决方案1】:

Parallel.Invoke 并行运行所有函数。由于 function2 不应在 function1 之前运行,因此请创建一个在后台按顺序运行它们的任务。

Task.Factory.StartNew(() =>
{
    function1();
    function2();
    function3();
});

如果我的计时器设置为 5 秒,但在 5 秒后功能 1、2 和 3 未完成,该怎么办

您可以使用bool 来查看它们是否已完成。

【讨论】:

    【解决方案2】:

    使用System.Threading.TimerThreadPool 线程上安排回调,因此您无需创建新任务。它还允许您控制间隔以防止回调重叠。

    // fired after 5 secs, but just once.
    _timer = new System.Threading.Timer(Callback, null, 5000, Timeout.Infinite);
    
    // on the callback you must re-schedule the next callback time;
    private void Callback(Object state) {
       Function1();
       Function2();
    
       // schedule the next callback time 
       _timer.Change(5000, Timeout.Infinite);
    }
    

    【讨论】:

      【解决方案3】:

      你看过任务吗?

      你可以这样做:

      Task[] tasks = new Task[3];
      tasks[0] = Task.Factory.StartNew(() => Function1());
      tasks[1] = Task.Factory.StartNew(() => Function2());
      tasks[2] = Task.Factory.StartNew(() => Function3());
      Task.WaitAll(tasks);
      

      以上将允许您并行运行函数,这就是您想要的。

      如果您不想在 timer1_Tick 内阻塞等待所有任务完成,则不要使用 WaitAll...。相反,您可以通过检查任务上的 IsCompleted 来检查任务是否已完成您的计时器再次触发......然后决定是否发出下一批功能。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-22
        • 1970-01-01
        • 2012-07-03
        相关资源
        最近更新 更多