void WorkerThreadMain() { ISequence seq; TimeSpan currentTime = TimeSpan.Zero; Stopwatch progTime = new Stopwatch(); TimeSpan lastGraphPin = TimeSpan.Zero; TimeSpan nextGraphPin = GraphPinInterval; Stopwatch freeTime = new Stopwatch(); NetworkUdpFrame netframe; while (isRunning) { // ### check incoming network traffic WorkerProcessNetworkTraffic(); // ### check triggers WorkerProcessTriggers(); // ### prepare next frame with preset time target lock ( mProgramLock ) { seq = mCurrentProgram; if (mTimeResetNextFrame) { currentTime = TimeSpan.Zero; mTimeResetNextFrame = false; // @todo: HACK HACKITY HACK HACK var glims = new List <IGlimDevice>(); Devices.ForEachDevice(g => glims.Add(g)); seq.SetDiscoveredDevices(glims); // make bindings Devices.ResetAllBindings(seq.Devices); } } seq.SetCurrentTime(currentTime); seq.FrameExecute(); netframe = new NetworkUdpFrame(); Devices.ForEachDevice(g => netframe.AddRange(g.IPEndPoint, g.MarshalNetworkMessages())); if (TimeSpan.Zero == currentTime) { // ### special condition for first frame Network.Send(netframe); progTime.Restart(); lastGraphPin = TimeSpan.Zero; nextGraphPin = GraphPinInterval; } else { // ### record some frame statistics.. if (progTime.Elapsed >= nextGraphPin) { // maintain graph pins... //Debug.WriteLine( "spanTime.ElapsedMilliseconds [{0}] freeTime.ElapsedMilliseconds [{1}]", spanTime.ElapsedMilliseconds, freeTime.ElapsedMilliseconds ); //Debug.WriteLine( "currentTime {0}, progTime.Elapsed {1}", currentTime, progTime.Elapsed ); double markPeriod = (progTime.Elapsed - lastGraphPin).TotalMilliseconds; double ratioUsed = 1.0 - ((double)freeTime.ElapsedMilliseconds / markPeriod); lock ( mWorkerFrameHistogram ) { mWorkerFrameHistogram.PushSample(Math.Max(0, ratioUsed)); } lastGraphPin = progTime.Elapsed; nextGraphPin = lastGraphPin + GraphPinInterval; freeTime.Reset(); HistogramChanged?.Invoke(this, new EngineHistorgramUpdatedEventArgs(mWorkerFrameHistogram.GenerateBitmap())); } // ### spin until frame target freeTime.Start(); while (currentTime - progTime.Elapsed > LongSleepThreshold) { Thread.Sleep(1); } while (currentTime > progTime.Elapsed) { Thread.Sleep(0); } freeTime.Stop(); // ### send all assembled frame data Network.Send(netframe); } // ### set next frame target currentTime += FrameTimeInterval; if (currentTime < progTime.Elapsed) { // @todo: can't keep up! need to log a warning? // match speed to max... currentTime = progTime.Elapsed; } } }
protected void OnHistogramUpdated() { HistogramChanged?.Invoke(this, EventArgs.Empty); }