// Start computation thread when Page appears on the screen Loaded += (s, e) => { thread = new Thread(ModelRun); isUnloaded = false; thread.Start(); };
// Stop computation thread when Page is removed from the screen Unloaded += (s, e) => { isUnloaded = true; renderComplete.Set(); thread.Join(); }; }
privatevoidModelRun() { while (!isUnloaded) { // Data array is updated for (int i = 0; i < N; i++) y[i] = Math.Cos(i * Math.PI / 50 + phase); phase += 0.1;
// Plot the computed array. // PlotY and Subscribe methods must be called from the UI dispatcher thread. // Unlike ConcurrentMarkerGraphSample here we wait for each frame to be rendered. if (!isUnloaded) { renderComplete.Reset(); Dispatcher.BeginInvoke(PlotData); renderComplete.WaitOne(); } } }
privatevoidPlotData() { // To increase responsiveness of the UI HeatmapGraph objects prepare // images to be drawn in a background thread. The Plot method cancels // current incomplete images before starting a new one. This may result // in loss of certain or even all of the frames. // The following code shows how to wait until a certain data is actually drawn. long id = markers.PlotY(y); // receive a unique operation identifier markers.RenderCompletion // an observable of completed and cancelled operations .Where(rc => rc.TaskId == id) // filter out an operation with the known id .Subscribe(dummy => { renderComplete.Set(); }); // signal when the id is observed } } }
This sample shows how to plot data that are computed in separated thread. Unlike ConcurrentMarkerGraphSample, in this sample computational thread waits for each frame to be rendered. This is achieved by observing RenderCompletion event and signaling when render operation with specific ID is completed (see ‘PlotData’ method for details).
近期评论