Hi I have an app that uses a json file to monitor run intervals of emails. I use it as a simple way to store the times I run an email notification. But I've run into an issue where the user can run concurrent instances of this app. What happens then is that two instances can read that json file and if they both read that an email is not sent, both instances will send an email leading to duplicate emails.
This is how the code is (sampled down for replicability)
public class SummaryEmailStatus
{
public DateTime DateSent { get; set; }
public string ToolType { get; set; }
public bool IsSent { get; set; }
}
public static class JsonUtil
{
public static Dictionary<string, SummaryEmailStatus> EmailStatusKVP = new Dictionary<string, SummaryEmailStatus>();
public static bool CreateEmailItemJasonFile(string jsonFileName)
{
var summCfgEmailStatus = new SummaryEmailStatus
{
DateSent = DateTime.Parse("2022-01-01"),
ToolType = "CIM",
IsSent = false
};
EmailStatusKVP.Add(SummaryEmailJsonObjs.ConfigError, summCfgEmailStatus);
string json = JsonConvert.SerializeObject(EmailStatusKVP, Formatting.Indented);
File.WriteAllText(jsonFileName, json);
}
public static Dictionary<string, SummaryEmailStatus> ReadEmailItemJsonFromFile(string jsonFileName)
{
string json = File.ReadAllText(jsonFileName);
EmailStatusKVP = JsonConvert.DeserializeObject<Dictionary<string, SummaryEmailStatus>>(json);
return EmailStatusKVP;
}
public static void WriteSummEmailStatusJsonToFile(string summaryEmailType, SummaryEmailStatus emailItem)
{
//string json = JsonConvert.SerializeObject(emailItem, Formatting.Indented);
EmailStatusKVP[summaryEmailType] = emailItem;
string json = JsonConvert.SerializeObject(EmailStatusKVP, Formatting.Indented);
File.WriteAllText(ParserConfigFilesConstants.SummaryEmailJsonFilePath, json);
}
}
The issue is I am using File.WritallText and ReadAllText. Is there a way to do what I am doing but in a way that locks the file each time the CreateEmailItemJasonFile or ReadEmailItemJsonFromFile or WriteSummEmailStatusJsonToFile is called?
I want only one instance for the console application to use this file. If the other instance tries to use it, it should get some "being used by another program" exception.
I saw this solution How to lock a file with C#? but with how new I am to C# I am not sure how to use it for my own needs.
I also thought about using a lock object around my File.Write and File.Read sections but I was under the impression that would only work if its another thread within the console application instance:
lock (fileReadLock)
{
string json = File.ReadAllText(jsonFileName);
}