我编写了以下代码,运行正常,但问题是有时它会让我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.");
}
}
}
}
答案 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.");
}
}
}