WinForm与多个计时器

时间:2012-08-06 22:15:24

标签: c# winforms timer

我正在编写一个WinForm应用程序,每隔30秒或1分钟使用一次SNMP调用。

我有一个用于调用我的SNMP命令的计时器,但我想添加一个显示操作期间经过的总时间的texbox计数器。

我遇到了很多问题,所以这里有一个列表:

  1. 我希望我的SNMP计时器'计时器'在等待分配的时间之前执行一次,所以我让它在3秒后关闭,然后在我的处理程序中更改间隔。但这有时会使计时器多次关闭,这不是我想要的。
  2. 每次'计时器'熄灭且我的SNMP调用执行我的计时器'appTimer'变得不同步。我尝试了一个解决方法,我检查它是否在另一个处理程序中然后只是将计时器跳到适当的时间。哪个有效,但我觉得这太复杂了。
  3. 我知道的最后一个问题是,当我使用我的停止按钮停止我的应用程序时,该按钮并未完全退出应用程序。当我开始另一次运行时,两个计时器之间的时间变得更大,并且由于某种原因,我的计数计时器'appTimer'开始计数两倍。
  4. 我希望这个描述不会太混乱,但无论如何这里是我的代码:

    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;
            }
        }
    }
    

1 个答案:

答案 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年。