3

ここで私の最初の質問。失敗しないことを祈ります…

私は初心者の独学の趣味の C# プログラマーです (本、グーグル、msdn、自分用のアプリの作成)。私が忘れていたのはばかげた、または明白なことかもしれませんが、私はこの問題を自分で理解することはできません. Google は失敗したので、少し助けとガイダンスが必要です。

私は8時間からこれに行き詰まっており、今は真夜中に助けを求めています. すべてのヒントとアドバイスを歓迎します。

前もって感謝します!

説明

私は2つのフォームを持っています。OnButtomclick フォーム A は、問題のあるフォーム B を実行しています。他のすべてのもの(コントロールなど)の中でフォームBでは、scfile = Ncom.sendcmd("gsc|||" +DWith+"|||"+DHeigh+"$", false)x秒ごとにサーバーにコマンドを送信するスレッドでタイマーを実行しています。フォーム B が開いた後、タイマーとスレッドが起動されます。フォームBIには、最終的に値を変更する1つのコントロール(コンボボックス)とmyTimer.Interval、の値を制御するもう1つのコントロール(Tickbar)がDWithありますDHeigh

私の問題

そのフォーム B を閉じて再度n回開くと、タイマーが「ティック」するたびに、コマンドがn+1回実行されます。私はこれを理解することはできません。また、フォーム B を開いてDWithandをandに変更し、フォームを閉じてから再度開き、値をandに変更し、閉じてから再度開くと、タイマーティックごとに実行されることに気付きました。DHeigh1325

scfile = Ncom.sendcmd("gsc|||" +1+"|||"+3+"$", false);

scfile = Ncom.sendcmd("gsc|||" +2+"|||"+5+"$", false);

scfile = Ncom.sendcmd("gsc|||" +8+"|||"+9+"$", false);

だけの代わりに:

scfile = Ncom.sendcmd("gsc|||" +8+"|||"+9+"$", false);

ここで8、 と9は、フォーム B を開いた後のコマンドのデフォルト値です。

私が試したこと

スレッドが終了していないか、タイマーが停止していない可能性があります。そのため、My FormClosing イベントで、 (スレッドの中止/強制終了は悪い考えであることはわかっています)RDFormClosing(object sender, FormClosingEventArgs e)を含むすべてを試しましたが、それでもうまくいきませんでした。Thread.Abort();

好奇心から、myTimer.AutoReset値を false に変更しようとしました。それでも同じ問題です。x秒ごとに繰り返されなかっただけです。

私の質問

私は何を取りこぼしたか?フォーム B を閉じる前にタイマーを停止してスレッドを強制終了しても、なぜこれが発生するのですか? 修正方法は?

ソース

フォーム B は、フォーム A から次のように開きます。

void ButtonSDeClick(object sender, System.EventArgs e)
{
    rD form = new rD(Ncom);
    form.Show();
    form.Closed += new System.EventHandler(DesktopFormClosed);
}

Form BI には、次のようなものがあります。

public partial class rD : Form
{
        public NetworkCom Ncom;
    string scfile;
    static System.Timers.Timer  myTimer = new System.Timers.Timer(1000);
    static bool exitFlag = false;
    Thread displayupdater;
    public rD(NetworkCom _ncom)
    {
        // Other code
        Ncom = _ncom;
        displayupdater = rundisplay();
    }

    public Thread rundisplay()
    {
        exitFlag = false;
        Thread updateThread = new Thread(() => updatescreen());
        updateThread.Name = "display";
        updateThread.Start();
        return updateThread;            
    }

    public void updatescreen()
    {
        myTimer.AutoReset = true;
        myTimer.Elapsed += new ElapsedEventHandler(TimerEventProcessor);
            myTimer.Interval = 1000;
            myTimer.Start();
            while(exitFlag == false) 
            {
                Application.DoEvents();
            }

    }

    private void TimerEventProcessor(Object myObject,EventArgs myEventArgs) 
        {
        scfile = Ncom.sendcmd("gsc|||" +DWith+"|||"+DHeigh+"$", false);
    }

        void RDFormClosing(object sender, FormClosingEventArgs e)
    {
        exitFlag = true;
        myTimer.Stop();
        myTimer.Close();
        displayupdater.Abort();
    }
    // More inessential code
}
4

1 に答える 1

3

タイマーは静的ですが、フォームは静的ではありません。したがって、Elapsed を登録するたびに集計されます。他の誰かがコメントしたように、フォームを閉じるときにイベントを削除すると、それを処理する必要があります。

于 2013-05-10T13:50:46.990 に答える