void ThreadOp(object sender, DoWorkEventArgs ea) { System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; SRControlThread srct = (SRControlThread)sender; SRControl sr = srct.SRCtrl; string identifier = "<unset>"; sr.Log.TraceEvent(LogLevels.Verbose, 87200, "Starting new SR thread"); try { identifier = sr.Identifier; sr.Log.TraceEvent(LogLevels.Verbose, 87201, "SR {0} thread running ", identifier); do { sr.Log.TraceEvent(LogLevels.Verbose, 87202, "SR {0} thread wait for command", identifier); try { srct.opgate.Wait(srct.cts.Token); // wait for caller to set an operation in motion } catch (OperationCanceledException) { //NEXT: Should this do something. It is being thrown, but no action hn 9/23/2014 } if (CancellationRequested(srct)) { sr.Log.TraceEvent(LogLevels.Verbose, 87255, "SR {0} thread cancelled", identifier); break; } srct.callwait.Reset(); // make caller wait for results switch (srct.op) { case SROp.InitializeContext: sr.Log.TraceEvent(LogLevels.Verbose, 87203, "SR {0} InitializeContext", identifier); ushort numnutsd = sr.InitializeContext(sr.Meas, sr.Det); // sets sr.acquire_num_runs srct.ReportProgress(0, sr); break; case SROp.InitializeSR: try { sr.Log.TraceEvent(LogLevels.Verbose, 87204, "SR {0} InitializeSR", identifier); srct.status = sr.InitializeSR(srct.cts); if (srct.status != sr_h.SR_SUCCESS) // status here is an sr.h machine code only { // stop = true; caller will stop, thread itself cannot } ea.Result = srct.status; sr.InitTDState(); // uses sr.acquire_num_runs } catch (Exception e) { // do not set LastSRStatus because there may have never been one set, use the Meas status ea.Result = srct.status = srct.SRCtrl.LastMeasStatus = SR.SR_FAIL; sr.Log.TraceException(e, false); sr.Log.TraceEvent(LogLevels.Warning, 87259, "SR {0} InitializeSR failure ", identifier); } srct.ReportProgress(0, sr); break; case SROp.StartSRDAQ: sr.Log.TraceEvent(LogLevels.Verbose, 87205, "SR {0} StartSRDAQ", identifier); srct.status = sr.StartSRDAQ(); if (srct.status != SR.MEAS_CONTINUE) // MEAS_ABORT or MEAS_TERMINATE { // stop = true; caller will stop, thread itself cannot } ea.Result = srct.status; srct.ReportProgress((int)(100 * ((double)sr.run_number / (double)sr.acquire_num_runs)), sr); break; case SROp.WaitForResults: sr.Log.TraceEvent(LogLevels.Verbose, 87206, "SR {0} PollAndGetResults", identifier); srct.status = sr.PollAndGetResults(); ea.Result = srct.status; if ((srct.status == SR.ZERO_COUNT_TIME) || (srct.status == SR.SR_TRY_AGAIN)) // dev note: empty cycles are eliminated by this step { sr.run_number--; } else if (srct.status != SR.SUCCESS) // MEAS_ABORT or MEAS_TERMINATE { // stop = true; caller will stop, thread itself cannot } else { // sr.tds has the results now, caller must retrieve them manually using TransformResults sr.fraction += sr.Meas.AcquireState.run_count_time; // run this out-of-thread so that caller wait is reset prior to the restart in StartLMCAssay! Action <object> action = (object obj) => { System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; SRControlThread talsrct = (SRControlThread)obj; talsrct.SROpCompletedEvent(talsrct.status); }; Task signifyingnothing = Task.Factory.StartNew(action, srct); } srct.ReportProgress((int)(100 * ((double)sr.run_number / (double)sr.acquire_num_runs)), sr); break; case SROp.CloseSR: sr.Log.TraceEvent(LogLevels.Verbose, 87207, "SR {0} CloseDownSR", identifier); sr.CloseDownSR(); srct.ReportProgress(100, sr); break; case SROp.Shutdown: sr.Log.TraceEvent(LogLevels.Verbose, 87207, "SR {0} shutdown thread", identifier); break; case SROp.ReInitializeSR: try { sr.Log.TraceEvent(LogLevels.Verbose, 87208, "SR {0} ReInitializeSR", identifier); srct.status = sr.ReInitializeSR(); if (srct.status != sr_h.SR_SUCCESS) // status here is an sr.h machine code only { // stop = true; caller will stop, thread itself cannot } ea.Result = srct.status; sr.InitTDState(); // uses sr.acquire_num_runs } catch (Exception e) { // do not set LastSRStatus because there may have never been one set, use the Meas status ea.Result = srct.status = srct.SRCtrl.LastMeasStatus = SR.SR_FAIL; sr.Log.TraceException(e, false); sr.Log.TraceEvent(LogLevels.Verbose, 87260, "SR {0} ReInitializeSR failure ", identifier); } srct.ReportProgress(0, sr); break; } srct.opgate.Reset(); // wait again at the top of loop, but first check for cancel or stop in the while condition here srct.callwait.Set(); // release caller to get state and do work } while (!(srct.op == SROp.Shutdown) || CancellationRequested(srct)); // run until a cancel occurs, or caller specifies the Shutdown operation } catch (Exception e) { sr.Log.TraceException(e, true); sr.Log.TraceEvent(LogLevels.Verbose, 87257, "SR ThreadOp bonk {0}", identifier); } sr.Log.TraceEvent(LogLevels.Verbose, 87297, "SR {0} thread exiting", identifier); srct.callwait.Set(); // release caller to get state and do work //srct.SROpCompletedEvent(srct.status); // signal failure via the final event if ungraceful exit in play }
bool CancellationRequested(SRControlThread srct) { return NC.App.Opstate.IsQuitRequested || // globally? srct.CancellationPending || // via the thread AsyncCancel() op srct.cts.IsCancellationRequested; // via the threads personal token }
bool CancellationRequested(SRControlThread srct) { return(NC.App.Opstate.IsQuitRequested || // globally? srct.CancellationPending || // via the thread AsyncCancel() op srct.cts.IsCancellationRequested); // via the threads personal token }
public SRControl StartSRControl(SRInstrument sr, ProgressChangedEventHandler pceh, SROpCompletedEventHandler opeh) { SRControlThread srct; if (threads.ContainsKey(sr.id)) { srct = threads[sr.id]; return srct.SRCtrl; // what? } // lookup the associated detector for the SRInstrument (match on DSID) Detector det = meas.Detectors.GetIt(sr.id); // must be there! srct = new SRControlThread(threads.Count + 1, logger, meas, det); srct.sri = sr; threads[sr.id] = srct; srct.WorkerReportsProgress = true; srct.WorkerSupportsCancellation = true; srct.DoWork += new DoWorkEventHandler(ThreadOp); srct.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Done); srct.ProgressChanged += new ProgressChangedEventHandler(pceh); srct.SROpCompleted += new SROpCompletedEventHandler(opeh); srct.RunWorkerAsync(sr); return srct.SRCtrl; }