Background: I need to use a scheduled task to scan a data table (1 minute scan once, or maybe 30 seconds once), the data table will increase the record, the data table in the third source of data, with the collection as a parameter to do a Thing, the time required for this matter can not be determined (an http request), after the completion of the revised state of each database records, to avoid the next scan again when the query out.
public class ScanJob : IJob
{
//Simulation of the data table, the reality of his records will not increase.
public static List<Person> persions = new List<Person>
{
new Person() { Name = "aaa", Status = true },
new Person() { Name = "bbb", Status = true },
new Person() { Name = "ccc", Status = true },
new Person() { Name = "ddd", Status = true },
new Person() { Name = "eee", Status = true },
};
//Intermediate variable, to avoid the previous has not yet ended, the next time has begun
public static List<string> process = new List<string>();
public void Execute(IJobExecutionContext context)
{
//Equivalent to a database query
var pers = persions.Where(s => s.Status).ToList();
//Exclude the object that was executed the previous time
pers = pers.Where(s=> !process.Contains(s.Name)).ToList();
Action<List<Person>> doWork = (s) =>
{
process.AddRange(s.Select(n => n.Name));//Add to intermediate variable
DoWork(s);//Do something that can not be expected time (http request)
};
doWork.BeginInvoke(pers, (str) =>
{
//After DoWork() ends, organize the intermediate variables
if (pers != null && pers.Count() > 0)
{
foreach (var i in pers)
process.Remove(i.Name);
}
}, null);
Console.ReadKey();
}
public void DoWork(List<Person> _pers)
{
Thread.Sleep(1000 * 60 * 1 + 1000 * 10);//Simulate http requests (One minute 10 seconds)
var firstPer = persions.Where(s => s.Status).FirstOrDefault();
if (firstPer != null)
{
//Simulation to modify the table record
firstPer.Status = false;
}
}
}
Because multiple job triggers are shorter, and the DoWork () method execution time is unpredictable, it may cause multiple threads to access the persions variable at the same time. How can I use the lock statement to handle this problem?