0

一般に、ガベージコレクションはリソースを解放するため、ガベージコレクションを行うことをお勧めします。keepingTime次のコードのメソッドで正しいガベージコレクションを実装するにはどうすればよいですか?または、実際には、私もする必要がありますか?!

System.Timers.TimerIDisposableインターフェイスを許可するため、「using」はオプションですが、タイマーのスコープをmyTimer_ElapsedTimer Elapsedイベントにサブスクライブするメソッドに拡張する必要があるため、以下では使用できません。ガベージコレクトを2回試みましたが、タイマーが十分に長くハングしないため、両方とも失敗します。

私は以前、他の理由でこのコードについてここで議論しました

public partial class AirportParking : Form
{

    //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //instance variables of the form
    System.Timers.Timer myTimer;

    private const string EvenText = "hello";
    private const string OddText = "hello world";

    static int tickLength = 100; 
    static int elapsedCounter;
    private int MaxTime = 5000;
    private TimeSpan elapsedTime; 
    private readonly DateTime startTime = DateTime.Now; 
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


    public AirportParking()
    {
        InitializeComponent();
        lblValue.Text = EvenText;
        keepingTime();
    }

    //method for keeping time
    public void keepingTime() {

        myTimer = new System.Timers.Timer(tickLength);
        myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
        myTimer.AutoReset = true;
        myTimer.Enabled = true;
        myTimer.Start();

        //ATTEMPT_1.tried the following unsuccessfully
        //using (System.Timers.Timer myTimer = new System.Timers.Timer(tickLength))
        //{
        //    myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
        //    myTimer.AutoReset = true;
        //    myTimer.Enabled = true;
        //    myTimer.Start();
        //}

        //ATTEMPT_2.tried the following unsuccessfully
        //myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
        //myTimer.AutoReset = true;
        //myTimer.Enabled = true;           
        //try
        //{
        //    myTimer.Start();
        //}
        //finally
        //{
        //    myTimer.Dispose();
        //}

    }

    private void myTimer_Elapsed(Object myObject,EventArgs myEventArgs){

        elapsedCounter++;
        elapsedTime = DateTime.Now.Subtract(startTime);

        if (elapsedTime.TotalMilliseconds < MaxTime)
        {
            this.BeginInvoke(new MethodInvoker(delegate
            {
                this.lblElapsedTime.Text = elapsedTime.ToString();

                if (elapsedCounter % 2 == 0)
                    this.lblValue.Text = EvenText;
                else
                    this.lblValue.Text = OddText;
            }));
        }
        else {myTimer.Stop();}
    }
}
4

3 に答える 3

2

OnClosingこれがメインフォームでない場合、またはちなみに、常に表示されるフォームである場合は、 フォームのイベントでタイマーを破棄します。

擬似コードは次のようになります。

public partial class AirportParking : Form
{
  .....
  .....

  protected override void OnClosing(...)
  {
       myTimer.Dispose();
  }
}

これが「長期的な」形式である場合は、不要になった時点でタイムレの廃棄を追加する必要がありますが、すでにご存知だと思います。

于 2012-04-18T07:24:04.380 に答える
2

タイマーリソースを破棄したい唯一の場所は、コールバック関数myTimer_Elapsedです。どこで行うmyTime.Stop();こともできますmyTimer.Dispose();

ただし、アプリケーションのこの部分がスコープ外になると、これらの変数はすべてクリーンアップされます。タイマーが最終的に停止している限り、参照が解除されると、GCによって収集されます。

usingブロック(および現在の)が機能しない理由はDispose()、タイマーを作成するとすぐにタイマーを破棄するためです。バックグラウンドで実行する必要があります。

于 2012-04-18T07:25:26.080 に答える
1

ガベージコレクションを行うことをお勧めしますが、この場合、フォームを閉じるかインスタンスが停止すると、ガベージコレクションが自動的に実行されます。

私がこれについて本当に心配しているのは、SQLリーダーを使用する場合だけです。終了したら、SQLリーダーが閉じられていることを確認する必要があります。そうしないと、あらゆる種類の問題が発生します。

于 2012-04-18T10:05:34.367 に答える