首页  ·  知识 ·  编程语言
c#即时监控小程序
曾祥展     .NET  编辑:dezai   图片来源:网络
#0000ff实时监控小程序 关键词:spa
实时监控小程序

关键词:
委托 线程 异步操作 大数据存储过程分页 实时刷新界面数据 声音报警 任务栏提示 动态任务栏图标切换

需求:启动监控程序后,每隔10秒(可配置多少秒)从后台数据库查询一次,
查询条件(sql语句可配置),然后返回结果显示和进行判断。
判断的条件(尽量也可以灵活配置):再返回的数据里面,空号2大于0的多少倍,
就要间隔1秒再取一次,如果发现还是2的倍数大,那就就报警,
如果0的倍数大于2很多,就每隔10秒(可配置)查询一次

即时插入的数据:(第一列)
程序界面:
 
配置:
 
报警_1~1.PNG
 
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();
}
}
}
 
下载源程序:即时监控小程序
 
 
本文作者:曾祥展 来源:网络
CIO之家 www.ciozj.com 微信公众号:imciow
    >>频道首页  >>网站首页   纠错  >>投诉
版权声明:CIO之家尊重行业规范,每篇文章都注明有明确的作者和来源;CIO之家的原创文章,请转载时务必注明文章作者和来源;
延伸阅读
也许感兴趣的
我们推荐的
主题最新
看看其它的