一個c#即時監控小程式
阿新 • • 發佈:2019-01-26
程式介面:
配置:
實現程式碼:
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Drawing; using System.IO; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; namespace SMMMMonitoring { public partial class Form1 : Form { private static string strConn = ConfigurationManager.AppSettings["conStr"];; private static string strProcedure = ConfigurationManager.AppSettings["procName"]; private static int pageindex =Convert.ToInt32( ConfigurationManager.AppSettings["pageindex"]);//重新整理第幾頁 private static int multiples = Convert.ToInt32(ConfigurationManager.AppSettings["Multiple"]);//報警倍數 StoreProcedure sa = new StoreProcedure(strProcedure, strConn); public Form1() { InitializeComponent(); BindDGV(); } private void BindDataWithPage(int Index) { winFormPager1.PageIndex = Index; string table = ConfigurationManager.AppSettings["table"]; string field = ConfigurationManager.AppSettings["Field"]; string orderby = ConfigurationManager.AppSettings["orderby"]; string where = ConfigurationManager.AppSettings["where"]; DataTable dt = sa.ExecuteDataTable(table, field, orderby, 10, Index, 0, 0, where); dataGridView1.DataSource = dt; winFormPager1.RecordCount = Convert.ToInt32(sa.ExecuteDataTable(table, field, orderby, 10, Index, 1, 0, where).Rows[0][0]); } private void winFormPager1_PageIndexChanged(object sender, EventArgs e) { BindDataWithPage(winFormPager1.PageIndex); } //執行緒間操作無效: 從不是建立控制元件“dataGridView1”的執行緒訪問它。 //呼叫 : BindDGV(9,BindDataWithPage); 傳遞引數 /* private delegate void BindDGVDelegate(int n); private void BindDGV(int n, BindDGVDelegate myDelegate) { if (this.InvokeRequired) { this.Invoke(myDelegate, n);//同步 } else { myDelegate(n); } } */ /* * Control的Invoke和BeginInvoke的委託方法是在主執行緒,即UI執行緒上執行的。 * 也就是說如果你的委託方法用來取花費時間長的資料,然後更新介面什麼的, * 千萬別在UI執行緒上呼叫Control.Invoke和Control.BeginInvoke,相對於invokeThread執行緒同步的,因為這些是依然阻塞UI執行緒的,造成介面的假死。 * 用Thread來呼叫BeginInvoke和Invoke * 執行順序: A--- BC (B和C同時執行,B執行線上程UI上,C執行線上程beginInvokeThread上) --DE */ private Thread beginInvokeThread; private delegate void beginInvokeDelegate(); private void StartMethod() { //C程式碼段...... 耗費長時間的操作 dataGridView1.BeginInvoke(new beginInvokeDelegate(beginInvokeMethod)); //D程式碼段...... 刪掉 } private void beginInvokeMethod() { //E程式碼段 更新介面的方法。 BindDataWithPage(pageindex); } private void BindDGV() { //A程式碼段....... beginInvokeThread = new Thread(new ThreadStart(StartMethod)); beginInvokeThread.Start(); //B程式碼段...... } /// <summary> /// 大於多少倍就報警 /// </summary> /// <param name="dgv"></param> /// <param name="n"></param> public bool Alarm(DataGridView dgv, int n) { int Space = 0; int Success = 0; Dictionary<string, int> dict = DictionaryColumns(dgv); foreach (KeyValuePair<string, int> kvp in dict) { if (kvp.Key == "2") { Space = kvp.Value; } if (kvp.Key == "0") { Success = kvp.Value; } } if (Space >= Success * n) { //報警 // MessageBox.Show("報警!", "資訊提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return true; } else { //MessageBox.Show("bu報警!", "資訊提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return false; } } public Dictionary<string, int> DictionaryColumns(DataGridView dgv) { Dictionary<string, int> dct = new Dictionary<string, int>(); string str = ""; for (int i = 0; i < dgv.Rows.Count - 1; i++) { str = Convert.ToString(dgv.Rows[i].Cells[4].Value); if (dct.ContainsKey(str))//如果字典中已存在這個鍵,給這個鍵值加1 { dct[str]++; } else { dct.Add(str, 1);//字典中不存在這個鍵,加入這個鍵 } } return dct; } private DateTime lastRefresh = new DateTime(0); private int refreshInterval = 10; private string lastTitle = string.Empty; private string lastMessage = string.Empty; /// <summary> /// 更新資料 /// </summary> public void RefreshAllMessages() { BindDGV(); } /// <summary> /// 更新待辦事情 /// </summary> private void RefreshAsync() { //更新最後執行時間 UpdateLastRefreshTime(); //建立查詢中狀態 BuildMessagesQuerying(); // 非同步更新 為了不卡住 RefreshAllMessagesDelegate refresher = new RefreshAllMessagesDelegate(this.RefreshAllMessages); IAsyncResult result = refresher.BeginInvoke(new AsyncCallback(RefreshAllCallback), refresher); //等待更新完成 while (!result.IsCompleted) { Application.DoEvents(); //在不加的時候,因為優先順序的問題,程式會執行主程序的程式碼,再執行Tick的程式碼,而加了以後就可以同步執行。 } //更新完成,警報並顯示待辦件數 BuildMessagesResult(); } /// <summary> /// 更新最後執行時間 /// </summary> private void UpdateLastRefreshTime() { this.lastRefresh = DateTime.Now; //時間為n秒之間 refreshInterval = int.Parse(this.txtRefreshInterval.Text); lblNextRefreshTime.Text = String.Format("{0:yyyy/MM/dd HH:mm:ss}", lastRefresh.AddSeconds(refreshInterval)); ; } /// <summary> /// 建立查詢中狀態 /// </summary> private void BuildMessagesQuerying() { lastMessage = "正在檢查中....."; // linkTodo.Enabled = false; // linkTodo.Text = lastMessage; btnRefresh.Enabled = false; mnuExit.Enabled = false; txtRefreshInterval.Enabled = false; // 將icon改成更新中,改成Refresh.ico ChangeNotifyIcon(NotifyIconType.Actions); } /// <summary> /// 依最後結果設定頁面 /// </summary> private void BuildMessagesResult() { bool IsShowNotify = Alarm(dataGridView1, multiples); //如果有待辦件數的話,就改成報警,否則就使用原始 ChangeNotifyIcon(IsShowNotify ? NotifyIconType.Phonographe : NotifyIconType.rabbit); notifyIcon1.Text = lastMessage; mnuExit.Enabled = true; txtRefreshInterval.Enabled = true; if (IsShowNotify && this.WindowState == FormWindowState.Minimized || IsShowNotify) { //要顯示通知資訊 PlaySound("msg.wav", true, true, false);//報警 lastMessage = "報警……"; notifyIcon1.ShowBalloonTip(3000, this.Text,lastMessage, ToolTipIcon.Info); } } //回非同步調 public delegate void RefreshAllMessagesDelegate(); static void RefreshAllCallback(IAsyncResult result) { //委託 Form1.RefreshAllMessagesDelegate dlgt = (Form1.RefreshAllMessagesDelegate)result.AsyncState; // 呼叫 EndInvoke 返回結果 dlgt.EndInvoke(result); } /// <summary> /// 實時更新 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void refreshTimer_Tick(object sender, EventArgs e) { TimeSpan diff = DateTime.Now - this.lastRefresh; if (diff > new TimeSpan(0,0, refreshInterval)) { //更新 StopSound(); RefreshAsync(); } } /// <summary> /// 更換NotifyIcon /// </summary> private void ChangeNotifyIcon(NotifyIconType notiType) { const string imageFolderName = "Resources"; try { //內嵌資源名稱 namespace.foldername.filename 而且大小寫要相同哦 圖片-右鍵屬性-嵌入的資源 System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly(); string fileName = asm.GetName().Name + "." + imageFolderName + "." + notiType.ToString() + ".ico"; Stream iconStream = asm.GetManifestResourceStream(fileName); Icon newIcon = new Icon(iconStream); this.notifyIcon1.Icon = newIcon; iconStream.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } public enum NotifyIconType { rabbit, Actions, Phonographe } #region 報警聲音 /* 當例如監測xx大於xx * 通過PlaySound(”msg.wav”, true, true, false)方法實現連續報警 * 還可以同時彈出視窗提醒之類的資訊. * 關閉報警通過方法StopSound()實現就可以了.*/ [DllImport("winmm.dll", EntryPoint = "PlaySound")] private static extern bool Win32_PlaySound(string pszSound, IntPtr hmod, uint fdwSound); /// <summary> /// 播放一個wav音訊檔案 /// </summary> /// <param name="path"></param> /// <param name="asynchronous"></param> /// <param name="loop"></param> /// <param name="doNotStopPlay"></param> public static void PlaySound(string path, bool asynchronous, bool loop, bool doNotStopPlay) { Win32_PlaySound(path, IntPtr.Zero, (uint)((asynchronous ? PlaySoundMessage.SND_ASYNC : PlaySoundMessage.SND_SYNC) | (loop ? PlaySoundMessage.SND_LOOP : 0) | (doNotStopPlay ? PlaySoundMessage.SND_NOSTOP : 0) | PlaySoundMessage.SND_FILENAME)); } /// <summary> /// 停止播放 /// </summary> public static void StopSound() { Win32_PlaySound(null, IntPtr.Zero, 0); } [Flags()] internal enum PlaySoundMessage { SND_SYNC = 0x0000, SND_ASYNC = 0x0001, SND_LOOP = 0x0008, SND_NOSTOP = 0x0010, SND_FILENAME = 0x00020000 } #endregion #region 窗體事件 private void notifyIcon1_DoubleClick(object sender, EventArgs e) { ShowForm(); } private void ShowForm() { if (this.WindowState == FormWindowState.Minimized) { this.Show(); this.WindowState = FormWindowState.Normal; } this.Activate(); this.Focus(); } private void mnuExit_Click(object sender, EventArgs e) { this.WindowState = FormWindowState.Minimized; Close(); } /// <summary> /// 視窗關閉,程式並不關閉,而是最小化 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (this.WindowState != FormWindowState.Minimized) { e.Cancel = true; this.WindowState = FormWindowState.Minimized; notifyIcon1.Tag = string.Empty; notifyIcon1.ShowBalloonTip(3000, this.Text, "程式未結束,要結束請在圖示上按右鍵,選取結束功能!", ToolTipIcon.Info); } } /// <summary> /// 在NotifyBallonTip上按下Click,就將Form開啟出來 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) { ShowForm(); } #endregion private void btnSetting_Click(object sender, EventArgs e) { Setting st = new Setting(); st.Show(); } } }