0

非常に奇妙なバグがあり、理解できないようです。これをできる限りレイアウトします。

コンテキスト:別の場所にあるIPのグループについて継続的にpingを実行するアプリケーションがあります。(各デバイスが特定の時間に稼働しているかどうかを確認する必要があります)

バグ:ホストにpingを実行し、インターネットがダウンしている場合、アプリケーションはすべてのデバイスがダウンしていることを示します(必要に応じて)。ただし、アプリを閉じるとき、プロセス(メインのアプリexe)はまだ実行中であり、ルータートラフィックは継続的なpingがまだ実行中であることを示しています(同じ間隔)。だから、タイマーのように動き続けます。

ただし、アプリケーションが閉じられ、グループが起動すると、プロセスは正常に閉じられ、すべてのpingが停止します。

私はあなたたちが見たいと思うどんなコードでも提供することができます。最初に基本を説明します。

私はEquipmentObjというクラスを持っています。コンストラクター内で、連続したpingが開始されます(非同期)*これはすべて、メインフォームではなく、別のフォームで実行されることに注意してください。コンストラクターとプロパティ:

System.Timers.Timer TimerObj { get; set; }
public EquipmentObj(string ipAddress)
        {
                this.IP_Address = ipAddress;
                this.TimerObj = new System.Timers.Timer();
                this.TimerObj.Interval = 2000;
                this.TimerObj.Elapsed += TimerObj_Elapsed;
                this.TimerObj.AutoReset = true;
                this.start();
        }

開始および経過方法:

private void start()
        {
            this._requestStop = false;
            this.TimerObj.Start();
        }


        private void TimerObj_Elapsed(object sender, System.Timers.ElapsedEventArgs     e)
            {
                if(!_requestStop)
                    base.start_Ping(this.Ip_Address);
            }

基本クラス:

public void start_Ping(string ipAddress)
        {
            try
            {
                Ping pingSender = new Ping();


                // Create the event Handler 
                pingSender.PingCompleted += pingSender_PingCompleted;

                // Create the buffer
                // Reference buff size: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                byte[] packetData = Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
                // Create the pingOptions object
                PingOptions packetOptions = new PingOptions();
                // Parse the passed ip address to a proper ipaddress object
                IPAddress ip = System.Net.IPAddress.Parse(ipAddress);

                // Send async
                pingSender.SendAsync(ip, 1050, packetData, ip);
            }
            catch (Exception ex)
            {
                Error_Log.write_log(ex);
            }
        }

        public virtual void pingSender_PingCompleted(object sender, PingCompletedEventArgs e)
        {
            throw new NotImplementedException();
        }

実装されたPingComplete:

  public override void pingSender_PingCompleted(object sender, PingCompletedEventArgs e)
        {
            if (e.Reply.Status == IPStatus.Success)
                this.status = "On Line";
            else
            {
                this.status = "Off Line";
                this.setBounced = ++this.setBounced  ?? 1;
            }
            this.setResponse = e.Reply.RoundtripTime.ToString();
        }

最後に、フォームの終了時に呼び出される私のクリーンアップ:

 foreach (EquipmentObj obj in this.objectListView1.Objects)
                {
                    obj.Stop();
                }

ここに停止があります:

public void Stop()
       {
           this._requestStop = true; 
           this.TimerObj.Stop();
       }

私が試したこと:

  • 終了イベントにクリーンアップ(上記)を追加します。
  • タイマーをsystem.threadingタイマーからsystem.timerタイマーに移動しました。
  • idisposableを実装してみました。
  • フォームを閉じるイベントでタイマーをnullに設定します。
  • 呼び出しは、タイマーでそれ自体を破棄します。

これらはどれも機能していません。あまりにも多くのコードと記述で皆さんを圧倒しすぎなかったといいのですが。どんな助けでもいただければ幸いです。

4

1 に答える 1

0

私の最善の策は、Stopが呼び出される前に例外がスローされることです。try { } catchエラーを処理できるように、そこにさらにいくつかのステートメントを配置します。

同じスレッドで作成されていないオブジェクトにアクセスしようとすると、スレッドの問題が発生する可能性があります。

タイマーオブジェクトをいじったときにいつでも呼び出す必要があるかどうかを確認します。

void Stop()
{
    if (objectListView1.InvokeRequired)
    {
         objectListView1.BeginInvoke(new Action(Stop));
         return;
    }

    foreach (EquipmentObj obj in this.objectListView1.Objects)
    {
        obj.Stop();
    }
}
于 2013-03-21T20:29:39.317 に答える