【问题标题】:Execute code in console application every minute每分钟在控制台应用程序中执行代码
【发布时间】:2014-09-05 21:48:09
【问题描述】:

我有一个简单的 C# 应用程序,它从一个位置获取 PDF 并将其移动到另一个位置。

namespace MoveFiles
{
class Program
{
    public static string destinationPath = @"S:\Re\C";
    static void Main(string[] args)
    {

        //location of PDF files

        string path = @"S:\Can\Save";

        //get ONLY PDFs

        string[] filePath = Directory.GetFiles(path, "*.pdf");


        foreach (string file in filePath)
        {
            Console.WriteLine(file);
            string dest = destinationPath + "\\" + Path.GetFileName(file);
            File.Move(file, dest);
        }
        Console.ReadKey();


    }
}

}

如果我运行这个应用程序,它就可以工作,但是,我需要每分钟执行一次此代码。我可以使用task scheduler 每分钟运行一次应用程序,但不幸的是最短运行时间是 5 分钟。

我曾尝试使用while(true),但它不起作用。如果我在应用程序运行时将更多 PDF 文件添加到文件夹中,它不会将其移动到其他文件夹。

我在网上找到了使用Timer 的建议,但我遇到了问题:

static void Main(string[] args)   
{
    Timer t = new Timer(60000); // 1 sec = 1000, 60 sec = 60000
    t.AutoReset = true;
    t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
    t.Start();
  }
  private static void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  {
     // do stuff every minute
   }

但我得到编译器错误:

错误 2 参数 1:无法从 'int' 转换为 'System.Threading.TimerCallback' C:\Win\MoveFiles\MoveFiles\MoveFiles\Program.cs 22 33 MoveFiles

关于如何解决此问题的任何建议?

【问题讨论】:

  • 有两个Timer类,System.Threading.Timer和System.Timers.Timer。您有 System.Timers.Timer 的代码,但 Timer 正在解析为 System.Threading.Timer。我猜您还没有向我们展示 using for System.Threading。
  • @mikez,这就是整个应用程序,这个应用程序中没有更多代码......
  • 某处有 using 指令(例如using System;)。否则,那些对 Console、Path、Directory 等类的引用将无法编译。
  • 我希望我们可以将任务计划程序“Repear Task Min”更改为“1 Min”

标签: c# console-application


【解决方案1】:

解决方案比我想象的要容易。

这是我解决它的方法。这可能不是最好的解决方案,但它可以满足我的需要。

我创建了一个while 循环并使用Thread.Sleep(60000) 强制应用在再次执行之前进入睡眠状态。

namespace MoveFiles
{
class Program
{
    public static string destinationPath = @"S:\Re\C";
    static void Main(string[] args)
    {

        //location of PDF files

        while (true)
        {
            string path = @"S:\Can\Save";

            //get ONLY PDFs

            string[] filePath = Directory.GetFiles(path, "*.pdf");


            foreach (string file in filePath)
            {
                Console.WriteLine(file);
                string dest = destinationPath + "\\" + Path.GetFileName(file);
                File.Move(file, dest);
            }
            Thread.Sleep(60000);
        }

    }

}
}

【讨论】:

  • 对于我自己的项目,我正在考虑相同的解决方案。我只是不确定这是否会占用电脑上的大量内存?
  • @JorisDecraecker,不幸的是,我不记得它在运行时用了多少内存,因为我几年前使用过这段代码,但我不相信它足以占用机器。当然,就我而言,这段代码运行时间不超过 30 分钟。
  • 我找到了一种更好的方法来解决这个问题(至少对于我的问题)。我将在批处理程序上使用任务计划程序。如果程序失败,调度器会在 15 分钟后再次运行。
【解决方案2】:

在这里查看构造函数:http://msdn.microsoft.com/en-us/library/system.threading.timer(v=vs.110).aspx

这是此构造函数的方法签名之一:

Timer(TimerCallback, Object, Int32, Int32)

您不能仅使用间隔来实例化 System.Threading.Timer。要么改用 System.Timers.Timer (http://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx),要么您必须提供 TimerCallback、对象状态(可以为空)、到期时间和期限。请参阅此处:“参数”下的http://msdn.microsoft.com/en-us/library/2x96zfy7(v=vs.110).aspx

【讨论】:

    【解决方案3】:
    private static Timer timer;
    
    static void Main(string[] args)
    {
        timer = new Timer(timer_Elapsed);
        timer.Change(60000, 60000);
        Console.ReadKey();
    }
    
    private static void timer_Elapsed(object o)
    {
        // do stuff every minute
    }
    

    【讨论】:

    • 它永远不会转到private static void t_Elapsed(object o) 应用程序关闭...?
    • @user1426542 您需要以某种方式保持控制台应用程序处于活动状态。什么时候关门?
    • 这个应用程序应该至少运行一天。这是一个临时应用程序,可将文件从一个位置移动到另一个位置。当用户关闭应用程序时它应该关闭。
    • @user1426542 我编辑了答案,以便在用户按键时关闭。
    • 我在timer_Elapsed 事件中移动了移动文件的代码。现在,在这一行timer = new Timer(t_Elapsed); 我假设它应该去timer_Elapsed 执行代码......但它永远不会去那里......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    • 2021-07-20
    • 1970-01-01
    • 2014-10-20
    • 2011-06-24
    • 1970-01-01
    • 2011-12-31
    相关资源
    最近更新 更多