Windows服务中的另一个进程正在使用的文件

时间:2017-06-27 11:04:07

标签: c# file quartz.net topshelf

我编写了以下代码,运行正常,但问题是有时它会让我file being used by another process这两个作业正在访问和编写相同的文件。 ClickProfileJob首先运行并在5秒后重复,然后根据5秒的计划重复第二个作业ClickLikeJob。我已经看到了几个解决方案,它们提出了我在下面编写的using技术。

    using Quartz;
    using System;
    using System.IO;
    using Topshelf;
    using Topshelf.Quartz;

    namespace FinyaConsole
    {
     class Program
     {
        static void Main(string[] args)
        {
            userCreds creds = new userCreds();

            if (creds.checkUser().Length > 3)
            {
                HostFactory.Run(x =>
                {
                    x.Service<GiveHeartsService>(s =>
                    {
                        s.WhenStarted(service => service.OnStart());
                        s.WhenStopped(service => service.OnStop());
                        s.ConstructUsing(() => new GiveHeartsService());

                        s.ScheduleQuartzJob(q =>
                            q.WithJob(() =>
                                JobBuilder.Create<ClickProfileJob>().Build())
                                .AddTrigger(() => TriggerBuilder.Create()
                                    .WithSimpleSchedule(b => b
                                        .WithIntervalInSeconds(5)
                                        .RepeatForever())
                                    .Build()));

                        s.ScheduleQuartzJob(q =>
                            q.WithJob(() =>
                                JobBuilder.Create<ClickLikeJob>().Build())
                                .AddTrigger(() => TriggerBuilder.Create()
                                    .WithSimpleSchedule(b => b
                                        .WithIntervalInSeconds(5)
                                        .RepeatForever())
                                    .Build()));


                    });

                    //.DependsOnEventLog()

                    x.RunAsLocalSystem()
                        .StartAutomaticallyDelayed()
                        .EnableServiceRecovery(rc => rc.RestartService(1));

                    x.SetServiceName("FinyaHearts");
                    x.SetDisplayName("FinyaHearts");
                    x.SetDescription("This is a service.");
                });
            }
        }
    }
        public class ClickProfileJob : IJob
        {
            public void Execute(IJobExecutionContext context)
            {
                try
                {
                    using (StreamWriter sw = new StreamWriter(".\\visits_to_others.txt", true))
                    {

                        //Write a line of text
                        sw.WriteLine($"[{DateTime.Now}] Welcome from ClickProfileJob!");
                        Console.WriteLine($"[{DateTime.Now}] Welcome from ClickProfileJob!");
                        //System.IO.File.WriteAllText(@"path\visit_users.txt", userLink);
                        //Close the file
                        sw.Flush();
                        sw.Dispose();
                        sw.Close();
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception: " + e.Message);
                }
                finally
                {
                    //Console.WriteLine("Executing finally block.");
                }
            }
        }

        public class ClickLikeJob : IJob
        {
            public void Execute(IJobExecutionContext context)
            {
                try
                {
                    using (StreamWriter sw = new StreamWriter(".\\visits_to_others.txt", true))
                    {

                        //Write a line of text
                        sw.WriteLine($"[{DateTime.Now}] Welcome from ClickLikeJob!");
                        Console.WriteLine($"[{DateTime.Now}] Welcome from ClickLikeJob!");
                        //System.IO.File.WriteAllText(@"path\visit_users.txt", userLink);
                        //Close the file
                        sw.Flush();
                        sw.Dispose();
                        sw.Close();
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception: " + e.Message);
                }
                finally
                {
                    //Console.WriteLine("Executing finally block.");
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

这不是Quartz特定的问题。您可以使用SemaphoreSlim或更好的简单lock。只需创建一个基本作业并从中派生出其他作业。然后锁定两个作业中的LockObject

public abstract class LockableJobBase
{
    protected static object LockObject = new object();
}


public class ClickProfileJob : LockableJobBase, IJob
{
    public void Execute(IJobExecutionContext context)
    {
        try
        {
            lock (LockObject)
            {
                using (StreamWriter sw = new StreamWriter(".\\visits_to_others.txt", true))
                {
                    // your sw stuff
                }
            }

        }
        catch (Exception e)
        {
            Console.WriteLine("Exception: " + e.Message);
        }
        finally
        {
            //Console.WriteLine("Executing finally block.");
        }
    }
}

public class ClickLikeJob : LockableJobBase, IJob
{
    public void Execute(IJobExecutionContext context)
    {
        try
        {
            lock (LockObject)
            {
                using (StreamWriter sw = new StreamWriter(".\\visits_to_others.txt", true))
                {
                    // your sw stuff
                }
            }

        }
        catch (Exception e)
        {
            Console.WriteLine("Exception: " + e.Message);
        }
        finally
        {
            //Console.WriteLine("Executing finally block.");
        }
    }
}