void ComputeThreadFunc(object thread_data) { thread_timestamp data = thread_data as thread_timestamp; try { T result = ResultSource.ExtractResult(); lock (compute_thread_lock) { computed_result = result; computing = false; } } catch (Exception e) { background_exception = e; computing = false; last_exception_timestamp = data.timestamp; } }
void spawn_recompute() { Thread computer = null; lock (compute_thread_lock) { if (computing == false) { computing = true; active_thread_data = new thread_timestamp() { timestamp = this.result_timestamp }; ActiveComputeExceptions = new List <ModelingOpException>(); // maybe should go in active_thread_data ? computer = new Thread(ComputeThreadFunc); } } if (computer != null) { computer.Start(active_thread_data); } }
public OpResultOutputStatus <T> CheckForNewResult() { if (computing) { return(OpResultOutputStatus <T> .Computing()); } else if (result_valid) { return(OpResultOutputStatus <T> .Unavailable()); } else if (last_exception_timestamp == result_timestamp) { return(OpResultOutputStatus <T> .Unavailable()); } else { // the compute we were waiting for has finished, extract the resulting mesh T returnResult = default(T); bool spawn_new_compute = false; lock (compute_thread_lock) { returnResult = computed_result; computed_result = default(T); // situations where we will discard this result: // 1) it came back null. lets hope this is temporary... // 2) active_thread_data was null. This means we hadn't actually spawned // the compute thread yet. [TODO] maybe this should happen another way? // 3) the timestamp increment since we spawned the current comput thread. // Discard the result and spawn a new compute. bool use_result = (returnResult != null) && (active_thread_data != null) && (active_thread_data.timestamp == result_timestamp); if (use_result) { result_valid = true; } else { result_valid = false; spawn_new_compute = true; } active_thread_data = null; LastComputeExceptions = ActiveComputeExceptions; ActiveComputeExceptions = null; } if (spawn_new_compute) { spawn_recompute(); } if (returnResult == null) { return((computing) ? OpResultOutputStatus <T> .Computing() : OpResultOutputStatus <T> .Unavailable()); } else { return(OpResultOutputStatus <T> .Ready(returnResult, LastComputeExceptions)); } } }