标签:
/*
* The GUI update goals of this application are as follows:
*
* 1. We would like most, if not all, GUI updates to occur in the context of a
* job thread. This helps to avoid the case where GUI updates
* occur in a separate thread, causing job threads to block momentarily at
* arbitrary times (for some time critical applications, this behavior is
* not acceptable).
*
* 2. We would like to avoid repainting the GUI every time a new job result is
* available, as this rate is application dependent and can occur hundreds of
* times per second. Repainting at a very high rate wastes CPU cycles.
*
* The GUI update strategy of this application is as follows:
*
* 1. Two flags track the status of GUI updates:
* mHaveUnpaintedResults - tracks when new results are available that have
* not yet been painted. This flag is set every time a new user result
* is generated by the application.
* mMinimumGuiUpdateNeeded - indicates that painting is now required - we‘ve
* passed the minimum amount of time between paints and new results are
* available.
*
* 2. A timer (mMinimumGuiPeriodTimer) is set to go off every 50 ms. If the
* handler for this timer determines the we have unpainted results, then it
* sets the mMinimumGuiUpdateNeeded flag.
*
* 3. Every time a new user result is generated, the mMinimumGuiUpdateNeeded
* flag is checked (in the "UserResultAvailable" event handler). If an update
* is needed, it is performed immediately, which causes it to occur in the context
* of a job thread.
*
* 4. A second timer (mMaximumGuiPeriodTimer) is set to go off every 500 ms. This
* timer handles the case where user results are generated relatively slowly, or
* they stop being generated for some reason (triggers stop occurring, etc). The
* event handler for this timer performs a paint. In this case, the paint is not
* performed in a job thread.
*
* 5. The mMaximumGuiPeriodTimer is reset every time a paint occurs, such that its
* handler is only called if a paint has not happened in the last 500 ms.
*/
定义如下:
private const int mnMaximumPeriodMs = 500;
private const int mnMinimumPeriodMs = 50;
private System.Threading.Timer mTimerMaximumGuiPeriod;
private System.Threading.Timer mTimerMinimumGuiPeriod;
private bool mbMinimumGuiUpdateNeeded = false;
private bool mbHaveUnpaintedResults = false;
// setup the gui update timers
mTimerMaximumGuiPeriod = new System.Threading.Timer(new System.Threading.TimerCallback(mMaximumGuiPeriodTimer_Elapsed), null,
mnMaximumPeriodMs, mnMaximumPeriodMs);
mbMinimumGuiUpdateNeeded = false;
mbHaveUnpaintedResults = false;
mTimerMinimumGuiPeriod = new System.Threading.Timer(new System.Threading.TimerCallback(mMinimumGuiPeriodTimer_Elapsed), null,
mnMinimumPeriodMs, mnMinimumPeriodMs);
GUI update support
1 #region GUI update support 2 3 private void mMaximumGuiPeriodTimer_Elapsed(object obj) 4 { 5 UpdateGui(null, null); 6 Debug.WriteLine("mMaximumGuiPeriodTimer_Elapsed"); 7 } 8 9 private void mMinimumGuiPeriodTimer_Elapsed(object obj) 10 { 11 bool updateNow = false; 12 13 lock (mTimerMinimumGuiPeriod) 14 { 15 if (!mbMinimumGuiUpdateNeeded && !mbHaveUnpaintedResults) 16 { 17 ResetMaximumGuiUpdateTimer(); 18 } 19 else 20 { 21 updateNow = true; 22 mbMinimumGuiUpdateNeeded = true; 23 } 24 } 25 26 if ( 27 updateNow 28 && false 29 //&& mCurrentRunState == RunState.Stopped 30 ) 31 { 32 UpdateGui(null, null); 33 } 34 35 //Debug.WriteLine("mMinimumGuiPeriodTimer_Elapsed"); 36 } 37 38 private void ResetMaximumGuiUpdateTimer() 39 { 40 mTimerMaximumGuiPeriod.Change(mnMaximumPeriodMs, mnMaximumPeriodMs); 41 } 42 43 private void ResetMinimumGuiUpdateTimer() 44 { 45 mTimerMinimumGuiPeriod.Change(mnMinimumPeriodMs, mnMinimumPeriodMs); 46 } 47 48 private void UpdateGui(object sender, System.EventArgs e) 49 { 50 try 51 { 52 if (this.InvokeRequired) 53 { 54 IAsyncResult async = BeginInvoke(new System.EventHandler(UpdateGui), new object[] { sender, e }); 55 while ((!async.IsCompleted) 56 && (!async.AsyncWaitHandle.WaitOne(300, false))) ; 57 EndInvoke(async); 58 return; 59 } 60 61 62 lock (mTimerMinimumGuiPeriod) 63 { 64 mbHaveUnpaintedResults = false; 65 } 66 67 68 #region 用户界面刷新 69 70 //注意: 71 //当刷新耗时大于 msMaximumPeriodMs 时,mMaximumGuiPeriodTimer_Elapsed 起到作用 72 73 #region 方式1 74 //if (mEventUpdateGui != null) 75 //{ 76 // mEventUpdateGui(); 77 //} 78 #endregion 79 80 #region 方式二 81 OnGuiUpdating(); 82 UpdateGuiExt(); 83 OnGuiUpdated(); 84 #endregion 85 86 #endregion 87 88 89 //this.Update(); 90 91 ResetMaximumGuiUpdateTimer(); 92 ResetMinimumGuiUpdateTimer(); 93 lock (mTimerMinimumGuiPeriod) 94 { 95 mbMinimumGuiUpdateNeeded = false; 96 } 97 Debug.WriteLine("UpdateGui " + Environment.TickCount.ToString()); 98 } 99 catch (Exception ex) 100 { 101 string sErr = "UpdateGui Exception --> " + ex.ToString(); 102 Debug.WriteLine(sErr); 103 } 104 } 105 106 private void UpdateGuiIfNeeded() 107 { 108 // this function is called every time a new user result is available. 109 // it performs a paint if the minimum amount of time between paints has elapsed. 110 bool updateNeeded; 111 lock (mTimerMinimumGuiPeriod) 112 { 113 updateNeeded = mbMinimumGuiUpdateNeeded; 114 } 115 116 if (updateNeeded) 117 { 118 UpdateGui(null, null); 119 } 120 } 121 122 //public abstract void UpdateGuiExt();//abstract class 且 子类必须实现 123 124 125 126 #endregion
外部调用:
/// <summary>请求立即更新</summary> /// <param name="sender"></param> /// <param name="e"></param> public void RequestImmediateUpdate(object sender, System.EventArgs e) { lock (mTimerMinimumGuiPeriod) { mbMinimumGuiUpdateNeeded = true; } } /// <summary>界面数值复位</summary> public virtual void Reset() { } /// <summary>用户自定义界面刷新逻辑</summary> protected virtual void UpdateGuiExt() { } protected virtual void OnGuiUpdating() { } protected virtual void OnGuiUpdated() { }
标签:
原文地址:http://www.cnblogs.com/wagwei/p/4343115.html