C# 使用Windows服务编写同步应用程序以并行处理文件

C# 使用Windows服务编写同步应用程序以并行处理文件,c#,windows-services,sync,C#,Windows Services,Sync,我的windows服务器上有一个文件夹,人们将在其中上载CSV文件,C:\Uploads 我想写一个简单的windows服务应用程序,每5秒扫描一次这个上传文件夹,收集文件并以并行线程/每个文件?的方式处理它们?。但是,主扫描过程不应重叠,即需要锁定 所以,我是这样做的: 我知道这不是windows服务代码,它是一个测试想法的控制台应用程序 根据dcastro的回复更新了代码 当它运行时,如下所示: 这个看起来对吗?如果您有任何关于改进此功能的帮助/提示,我们将不胜感激。除了您不需要使用task

我的windows服务器上有一个文件夹,人们将在其中上载CSV文件,C:\Uploads

我想写一个简单的windows服务应用程序,每5秒扫描一次这个上传文件夹,收集文件并以并行线程/每个文件?的方式处理它们?。但是,主扫描过程不应重叠,即需要锁定

所以,我是这样做的: 我知道这不是windows服务代码,它是一个测试想法的控制台应用程序

根据dcastro的回复更新了代码

当它运行时,如下所示:


这个看起来对吗?如果您有任何关于改进此功能的帮助/提示,我们将不胜感激。

除了您不需要使用task.Factory.StartNew启动任务之外,我觉得这很好。System.Threading.Timer已在线程池上执行回调,因此无需启动另一个也将在线程池上运行的任务

此外,如果您的计时器每5秒滴答一次,并且您希望处理文件大约需要10秒,那么您的线程将开始排队等待释放锁。这发生在您发布的示例上

如果是这样的话,我要么将计时器的周期增加到10秒以上,要么用它代替常规的锁。TryEnter将尝试获取锁,并立即返回,无论是否获取了锁。如果锁当前被另一个线程占用,则只需完全跳过此勾号


你好谢谢你的反馈。同步应每5分钟运行一次。该任务需要10秒的原因是,处理文件可能需要多长时间,比如说要处理100个文件。这就是为什么锁定只在进程尚未处理时才执行进程的原因。根据您的反馈,我更新了我的代码,现在代码似乎被破坏了:当同步运行时,第一个周期工作,但当第二个周期开始时,应用程序关闭/退出。我没有收到同步正忙的消息…@LatheesanKanes _LockAcquired变量应该是方法的本地变量,而不是静态变量。让我知道这是否有效。抱歉,我没有意识到。在等待你的答复时,我开始考虑如何解决这个问题,并得出以下结论:看起来是这样的:现在可以了吗?或者我应该回到我在上面的回复中发布的其他代码并使用局部变量吗?还有,我第一次回答的意思是5秒而不是5分钟。@LatheesanKanes,你在什么地方找到的?看起来真的很恶心。。。没有理由抛出异常,然后立即捕获它,然后输入锁以再次释放它。。一团糟。是的,回到你所拥有的,并在try块之前声明bool。@LatheesanKanes这对我来说很好:我将计时器周期缩短到1秒,文件处理时间缩短到2秒
class Program
{
    static Timer _InternalTimer;
    static Object _SyncLock = new Object();

    static void Main(string[] args)
    {
        _InternalTimer = new Timer(InitProcess, null, 0, 5000); // Sync cycle is every 5 sec

        Console.ReadKey();
    }

    private static void InitProcess(Object state)
    {
        ConsoleLog("Starting Process");
        StartProcess();
    }

    static void StartProcess()
    {
        bool lockTaken = false;
        try
        {
            Monitor.TryEnter(_SyncLock, ref lockTaken);
            if (lockTaken)
            {
                ConsoleLog("Lock Acquired. Doing some dummy work...");

                List<string> fileList = new List<string>()
                {
                    "fileA.csv",
                    "fileB.csv"
                };

                Parallel.ForEach(fileList, (string fileName) =>
                {
                    ConsoleLog("Processing File: " + fileName);
                    Thread.Sleep(10000); // 10 sec to process each file
                });

                GC.Collect();
            }
            else
                ConsoleLog("Sync Is Busy, Skipping Cycle");
        }
        finally
        {
            if (lockTaken)
                Monitor.Exit(_SyncLock);
        }
    }

    static void ConsoleLog(String Message)
    {
        Console.WriteLine("[{0}]: {1}",
            DateTime.UtcNow.ToString("HH:mm:ss tt"),
            Message);
    }
}