我正在编写一个WinForm应用程序,每隔30秒或1分钟使用一次SNMP调用。
我有一个用于调用我的SNMP命令的计时器,但我想添加一个显示操作期间经过的总时间的texbox计数器。
我遇到了很多问题,所以这里有一个列表:
我希望这个描述不会太混乱,但无论如何这里是我的代码:
using System;
using System.Net;
using SnmpSharpNet;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public static bool stop = false;
static bool min = true, eye = false, firstTick = false;
static string ipAdd = "", fileSaveLocation = "";
static System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
static System.Windows.Forms.Timer appTimer = new System.Windows.Forms.Timer();
static int alarmCounter = 1, hours = 0, minutes = 0, seconds = 0, tenthseconds = 0, count = 0;
static bool inSNMP = false;
static TextBox textbox, timeTextbox;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
textbox = outputBox;
timeTextbox = timeBox;
ipAdd = "192.168.98.107";
fileSaveLocation = "c:/Users/bshellnut/Desktop/Eye.txt";
min = true;
inSNMP = false;
}
private void IPtext_TextChanged(object sender, EventArgs e)
{
ipAdd = IPtext.Text;
}
private void stopButton_Click(object sender, EventArgs e)
{
stop = true;
timer.Stop();
appTimer.Stop();
count = 0;
hours = minutes = seconds = tenthseconds = 0;
inSNMP = false;
}
// This is the method to run when the timer is raised.
private static void TimerEventProcessor(Object myObject,
EventArgs myEventArgs)
{
inSNMP = true;
timer.Stop();
if (firstTick == true)
{
// Sets the timer interval to 60 seconds or 1 second.
if (min == true)
{
timer.Interval = 1000 * 60;
}
else
{
timer.Interval = 1000 * 30;
}
}
// Displays a message box asking whether to continue running the timer.
if (stop == false)
{
textbox.Clear();
// Restarts the timer and increments the counter.
alarmCounter += 1;
timer.Enabled = true;
System.IO.StreamWriter file;
//if (eye == true)
//{
file = new System.IO.StreamWriter(fileSaveLocation, true);
/*}
else
{
file = new System.IO.StreamWriter(fileSaveLocation, true);
}*/
// SNMP community name
OctetString community = new OctetString("public");
// Define agent parameters class
AgentParameters param = new AgentParameters(community);
// Set SNMP version to 2 (GET-BULK only works with SNMP ver 2 and 3)
param.Version = SnmpVersion.Ver2;
// Construct the agent address object
// IpAddress class is easy to use here because
// it will try to resolve constructor parameter if it doesn't
// parse to an IP address
IpAddress agent = new IpAddress(ipAdd);
// Construct target
UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 1);
// Define Oid that is the root of the MIB
// tree you wish to retrieve
Oid rootOid;
if (eye == true)
{
rootOid = new Oid("1.3.6.1.4.1.128.5.2.10.14"); // ifDescr
}
else
{
rootOid = new Oid("1.3.6.1.4.1.128.5.2.10.15");
}
// This Oid represents last Oid returned by
// the SNMP agent
Oid lastOid = (Oid)rootOid.Clone();
// Pdu class used for all requests
Pdu pdu = new Pdu(PduType.GetBulk);
// In this example, set NonRepeaters value to 0
pdu.NonRepeaters = 0;
// MaxRepetitions tells the agent how many Oid/Value pairs to return
// in the response.
pdu.MaxRepetitions = 5;
// Loop through results
while (lastOid != null)
{
// When Pdu class is first constructed, RequestId is set to 0
// and during encoding id will be set to the random value
// for subsequent requests, id will be set to a value that
// needs to be incremented to have unique request ids for each
// packet
if (pdu.RequestId != 0)
{
pdu.RequestId += 1;
}
// Clear Oids from the Pdu class.
pdu.VbList.Clear();
// Initialize request PDU with the last retrieved Oid
pdu.VbList.Add(lastOid);
// Make SNMP request
SnmpV2Packet result;
try
{
result = (SnmpV2Packet)target.Request(pdu, param);
}
catch (SnmpSharpNet.SnmpException)
{
timer.Stop();
textbox.Text = "Could not connect to the IP Provided.";
break;
}
// You should catch exceptions in the Request if using in real application.
// If result is null then agent didn't reply or we couldn't parse the reply.
if (result != null)
{
// ErrorStatus other then 0 is an error returned by
// the Agent - see SnmpConstants for error definitions
if (result.Pdu.ErrorStatus != 0)
{
// agent reported an error with the request
textbox.Text = "Error in SNMP reply. " + "Error " + result.Pdu.ErrorStatus + " index " + result.Pdu.ErrorIndex;
lastOid = null;
break;
}
else
{
// Walk through returned variable bindings
foreach (Vb v in result.Pdu.VbList)
{
// Check that retrieved Oid is "child" of the root OID
if (rootOid.IsRootOf(v.Oid))
{
count++;
textbox.Text += "#" + count + " " + v.Oid.ToString() + " " + SnmpConstants.GetTypeName(v.Value.Type) +
" " + v.Value.ToString() + Environment.NewLine;
file.WriteLine("#" + count + ", " + v.Oid.ToString() + ", " + SnmpConstants.GetTypeName(v.Value.Type) +
", " + v.Value.ToString(), true);
if (v.Value.Type == SnmpConstants.SMI_ENDOFMIBVIEW)
lastOid = null;
else
lastOid = v.Oid;
}
else
{
// we have reached the end of the requested
// MIB tree. Set lastOid to null and exit loop
lastOid = null;
}
}
}
}
else
{
//Console.WriteLine("No response received from SNMP agent.");
textbox.Text = "No response received from SNMP agent.";
//outputBox.Text = "No response received from SNMP agent.";
}
}
target.Close();
file.Close();
}
else
{
// Stops the timer.
//exitFlag = true;
count = 0;
}
}
private static void ApplicationTimerEventProcessor(Object myObject,
EventArgs myEventArgs)
{
tenthseconds += 1;
if (tenthseconds == 10)
{
seconds += 1;
tenthseconds = 0;
}
if (inSNMP && !firstTick)
{
if (min)
{
seconds = 60;
}
else
{
textbox.Text += "IN 30 SECONDS!!!";
if (seconds < 30)
{
seconds = 30;
}
else
{
seconds = 60;
}
}
}
if(seconds == 60)
{
seconds = 0;
minutes += 1;
}
if(minutes == 60)
{
minutes = 0;
hours += 1;
}
timeTextbox.Text = (hours < 10 ? "00" + hours.ToString() : hours.ToString()) + ":" +
(minutes < 10 ? "0" + minutes.ToString() : minutes.ToString()) + ":" +
(seconds < 10 ? "0" + seconds.ToString() : seconds.ToString()) + "." +
(tenthseconds < 10 ? "0" + tenthseconds.ToString() : tenthseconds.ToString());
inSNMP = false;
firstTick = false;
}
private void eyeButton_Click(object sender, EventArgs e)
{
outputBox.Text = "Connecting...";
eye = true;
stop = false;
count = 0;
hours = minutes = seconds = tenthseconds = 0;
timer.Tick += new EventHandler(TimerEventProcessor);
timer.Interval = 3000;
firstTick = true;
appTimer.Tick += new EventHandler(ApplicationTimerEventProcessor);
appTimer.Interval = 100;
appTimer.Start();
timer.Start();
}
private void jitterButton_Click(object sender, EventArgs e)
{
outputBox.Text = "Connecting...";
eye = false;
stop = false;
count = 0;
hours = minutes = seconds = tenthseconds = 0;
timer.Tick += new EventHandler(TimerEventProcessor);
timer.Interval = 3000;
firstTick = true;
appTimer.Tick += new EventHandler(ApplicationTimerEventProcessor);
appTimer.Interval = 100;
appTimer.Start();
timer.Start();
}
private void Seconds_CheckedChanged(object sender, EventArgs e)
{
min = false;
}
private void Minutes_CheckedChanged(object sender, EventArgs e)
{
min = true;
}
private void exitButton_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void savetextBox_TextChanged(object sender, EventArgs e)
{
fileSaveLocation = savetextBox.Text;
}
}
}
答案 0 :(得分:3)
使用单个计时器非常容易。定时器具有1/10秒的分辨率(左右),可以直接用于更新经过的时间。然后,您可以使用该计时器中的相对经过时间来启动SNMP事务,并且可以动态地重新安排下一个事务。
这是一个简单的例子
using System;
using System.Drawing;
using System.Windows.Forms;
class Form1 : Form
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
DateTime lastSnmpTime;
TimeSpan snmpTime = TimeSpan.FromSeconds(30);
DateTime startTime;
TextBox elapsedTimeTextBox;
Timer timer;
public Form1()
{
timer = new Timer { Enabled = false, Interval = 10 };
timer.Tick += new EventHandler(timer_Tick);
elapsedTimeTextBox = new TextBox { Location = new Point(10, 10), ReadOnly = true };
Controls.Add(elapsedTimeTextBox);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
startTime = DateTime.Now;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
// Update elapsed time
elapsedTimeTextBox.Text = (DateTime.Now - startTime).ToString("g");
// Send SNMP
if (DateTime.Now - lastSnmpTime >= snmpTime)
{
lastSnmpTime = DateTime.Now;
// Do SNMP
// Adjust snmpTime as needed
}
}
}
更新了Q&amp; A
使用此代码,计时器会在I之后的开头触发一次 按停止按钮并调用timer.Stop()然后按我的开始 按钮计时器直到大约12秒后才会启动。将 重置DateTimes可以解决这个问题吗?
当用户按下“开始”按钮时,设置lastSnmpTime = DateTime.MinValue
。这导致(DateTime.Now - lastSnmpTime)的TimeSpan超过2000年,因此它将大于snmpTime并将立即触发。
此外,文本框中的输出时间如下所示:0:00:02.620262。 这是为什么?有没有办法让它只显示0:00:02.62?
当您减去两个DateTime值时,结果是TimeSpan值。我使用了"g"
@"d\:hh\:mm\:ss\.ff"
。您可以使用standard TimeSpan formatting string TimeSpan.MaxValue
来获取日期:小时:分钟:秒。分数(小数点后2位)。
计时器也会继续运行并打印到文本框 超过9个小时?因为我打算让它运行24小时+
如果您使用带有“d”的自定义格式显示天数,则会运行{{1}},这将超过10,675,199天,超过29,000年。