i'm trying figure out how comes request api call waiting backgroundworkers completed.
this jobmanager:
public class jobmanager { public list<abstractjob> jobs; public jobmanager() { jobs = new list<abstractjob>(); } public int newtestjob() { var job = new testjob(); job.name = "testjob"; jobs.add(job); return job.id; } public void startjob(int id) { var job = jobs.where(j => j.id == id).firstordefault(); if (job == null) throw new exception("not found"); job.execute(); } public string statusjob(int id) { var job = jobs.where(j => j.id == id).firstordefault(); if (job == null) throw new exception("not found"); return job.status; } public list<abstractjob> runningjobs() { return jobs.where(j => j.status == "running").tolist(); } } this ijob
public interface ijob { void execute(); } this abstractjob
public abstract class abstractjob : ijob { static int counter = 0; protected backgroundworker _bw = new backgroundworker(); public int id; public string status; public string name; public abstractjob() { interlocked.increment(ref counter); id = counter; _bw.workerreportsprogress = true; _bw.workersupportscancellation = true; _bw.dowork += new doworkeventhandler(bw_dowork); _bw.progresschanged += new progresschangedeventhandler(bw_progresschanged); _bw.runworkercompleted += new runworkercompletedeventhandler(bw_runworkercompleted); _bw.reportprogress(0, "idle"); } public virtual string describe() { return "not known 4 legged animal!"; } public void execute() { _bw.runworkerasync(); } private void bw_progresschanged(object sender, progresschangedeventargs e) { this.status = e.userstate.tostring(); } private void bw_runworkercompleted(object sender, runworkercompletedeventargs e) { backgroundworker worker = sender backgroundworker; if ((e.cancelled == true)) { this.status = "canceled"; } else if (!(e.error == null)) { this.status = "error"; } else { this.status = "done"; } } public abstract void bw_dowork(object sender, doworkeventargs e); } and job:
public class testjob : abstractjob { public override void bw_dowork(object sender, doworkeventargs e) { system.threading.thread.sleep(50000); // representing actual code takes time } } so wanted in controller create 10 jobs , return id's while tasks running in background.
public ienumerable<int> get() { var ids = new list<int>(); (int = 0; < 10; i++) { var id = jobm.newtestjob(); jobm.startjob(id); ids.add(id); } return ids; } this seem work great, except request waiting on sleeptimer in job. although when place breakpoint on return ids in controller; hit's fast (so async working)
normally should have message: "an asynchronous module or handler completed while asynchronous operation still pending." it considered dangerous launch background tasks without awaiting them
you should use taskparallellibrary - async/await do , wait tasks return:
public async task get() { var tasks = new list<task>(); (int = 0; < 10; i++) { tasks.add(task.run(() => { //your code here })); } await task.whenall(tasks); } if doing fireandforget can use new queuebackgroundworkitem framework 4.5.2.
also check out post. better use native async methods , transform whole chain async instead of doing "task.run".
Comments
Post a Comment