3

30秒または1分ごとにSNMP呼び出しを使用するWinFormアプリケーションを作成しています。

SNMPコマンドを呼び出すためのタイマーが機能していますが、操作中に経過した合計時間を表示するtexboxカウンターを追加したいと思います。

私が抱えている多くの問題があるので、ここにリストがあります:

  1. SNMPタイマー「タイマー」を1回実行してから、割り当てられた時間を待つようにしたいので、3秒でオフにしてから、ハンドラーで間隔を変更します。しかし、これによりタイマーが複数回オフになることがありますが、これは私が望んでいることではありません。
  2. 「タイマー」がオフになり、SNMP呼び出しが実行されるたびに、カウンタータイマー「appTimer」が同期しなくなります。他のハンドラーにあるかどうかを確認してから、タイマーを適切な時間にジャンプするという回避策を試しました。これは機能しますが、これが複雑になりすぎているように感じます。
  3. 私が知っている最後の問題は、アプリを完全に終了しない停止ボタンを使用してアプリケーションを停止したときに発生します。別の実行を開始すると、両方のタイマー間の時間がさらに長くなり、何らかの理由で、カウントタイマー「appTimer」が2倍の速度でカウントを開始します。

この説明があまり混乱しないことを願っていますが、とにかく私のコードは次のとおりです。

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

1 に答える 1

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&A

このコードを使用すると、タイマーは最初に1回起動し、停止ボタンを押してtimer.Stop()を呼び出してから開始ボタンを押すと、約12秒後までタイマーが起動しません。DateTimesをリセットするとこれは修正されますか?

ユーザーがスタートボタンを押したら、を設定しlastSnmpTime = DateTime.MinValueます。これにより、(DateTime.Now --lastSnmpTime)のTimeSpanが2,000年を超えるため、snmpTimeより大きくなり、すぐに起動します。

また、テキストボックスの出力時間は次のようになります:0:00:02.620262。何故ですか?0:00:02.62のみを表示する方法はありますか?

2つのDateTime値を引くと、結果はTimeSpan値になります。標準のTimeSpanフォーマット文字列を使用しました"g"のカスタムTimeSpanフォーマット文字列を使用して、 @"d\:hh\:mm\:ss\.ff"days:hours:minutes:seconds.fraction(小数点以下第2位)を取得できます。

また、タイマーが9時間以上実行されると、タイマーがオンになり、テキストボックスに出力されますか?これを24時間以上実行する予定なので

'd'を使用してカスタム形式を使用して日数を表示すると、TimeSpan.MaxValue10,675,199日をわずかに超える日数、つまり29、000年を超える日数が実行されます。

于 2012-08-06T23:28:53.527 に答える