J'ai écrit le code suivant qui fonctionne bien mais le problème est que parfois cela me donne file being used by another process
ces deux travaux accèdent et écrivent le même fichier. ClickProfileJob
s'exécute en premier et répète après 5 secondes, puis le deuxième travail ClickLikeJob
selon l'horaire de 5 secondes. J'ai vu quelques solutions qui avaient suggéré la même technique que j'ai codé ci-dessous.Fichier utilisé par un autre processus dans le service Windows
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.");
}
}
}
}
Vous avez donc 2 déclencheurs simultanés (plus ou moins) en même temps toutes les 5 secondes. Ceux-ci invoquent respectivement différentes méthodes qui tentent d'écrire dans le même fichier. Boom. Pourquoi ne pas avoir une seule minuterie qui invoque une méthode qui invoque les méthodes originales *** séquentiellement ***? De cette façon, leur exécution ne se chevauchera jamais. – spender
@spender J'ai essayé de changer les secondes comme 2 secondes pour le premier travail et 7 secondes pour le deuxième travail. Il donne encore parfois l'erreur. Ces deux tâches sont différentes parce que je veux utiliser le premier pour fonctionner comme chaque semaine et le deuxième travail est chronométré pour courir après 3 jours. – Amjad
Après 14 secondes? Penses-y. – spender