c# - Task Inside Loop -
i have windows service thread runs every 2 minutes.
while (true) { try { repneg.willexecuteloopwithtasks(param1, param2, param3); thread.sleep(20000); }
inside have loop tasks:
foreach (repmodel repmodelo in listarep) { task t = new task(() => { this.coletafunc(repmodelo.endip, user, tipofilial); }); t.start(); }
but think implementation wrong. need run 1 task every element in list, and, when specific task finishes, wait minute , start again.
m8's need have 2 situations here.
1 - can't wait task finish. because task can take more 2 hours finish , can take 27 seconds.
2 - list of tasks can change. thats why got thread. every 2 minutes thread list of tasks execute , start loop.
but task not finished yet , thread start again , strange things show in log. tryed use dictionry solve problem after time of execution, takes days, log show:
"system.indexoutofrangeexception"
here do...
create new class stores following (as properties):
- a
repmodel
id (something unique) - a
datetime
last time ran - a
int
frequency task should run in seconds - a
bool
determine if task in progress or not
then need global list of class somewhere, called "joblist".
your main app should have timer, runs every couple of minutes. job of timer check new repmodel
(assume these can change on time, i.e database list). when ticks, loops list , adds new ones (different id) joblist
. may want remove no longer required (i.e. removed db list).
then have second timer, runs every second. it's job check items in joblist
, compare last run time current time (and ensure not in progress). if duration has lapped, kick off task. once task complete, update last run time can work next time, ensuring change "in progress" flag go.
this theory , need give try yourself, think covers trying achieve.
some sample code (may or may not compile/work):
class job { public int id { get; set; } public datetime? lastrun { get; set; } public int frequency { get; set; } public bool inprogress { get; set; } } list<job> joblist = new list<job>(); // every 2 minutes (or whatever). void timermain_tick() { foreach (repmodel repmodelo in listarep) { if(!joblist.any(x => x.id == repmodelo.id) { joblist.add(new job(){ id = repmodel.id, frequency = 120 }); } } } // every 10 seconds (or whatever). void timertask_tick() { foreach(var job in joblist.where(x => !x.inprogress && (x.lastrun == null || datetime.compare(x.lastrun.addseconds(x.duration), datetime.now) < 0)) { task t = new task(() => { // task. }).continuewith(task => { job.lastrun = datetime.now; job.inprogress = false; }, taskscheduler.fromcurrentsynchronizationcontext());; job.inprogress = true; t.start(); } }
Comments
Post a Comment