關鍵詞:委託 線程 非同步作業 大資料存放區過程分頁 即時重新整理介面資料 聲音警示 工作列提示 動態工作列表徵圖切換
需求:啟動監控程式後,每隔10秒(可配置多少秒)從後台資料庫查詢一次,
查詢條件(sql語句可配置),然後返回結果顯示和進行判斷。
即時插入的資料:(第一列)
本例源碼程式
判斷的條件(盡量也可以靈活配置):再返回的資料裡面,空號2大於0的多少倍,
就要間隔1秒再取一次,如果發現還是2的倍數大,那就就警示,
如果0的倍數大於2很多,就每隔10秒(可配置)查詢一次
程式介面:
配置:
實現代碼:
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();
// 非同步更新 為了不卡住