1

global.asaxの Application_Start から呼び出す Timer 関数があります。

これはクラスです:

public class AlertTimer
{
    public AlertTimer()
    {
        //
        // TODO: Add constructor logic here
        //
    }
    static System.Timers.Timer aTimer = new System.Timers.Timer();
    public static void Start()
    {
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        aTimer.Interval = 30000;
        aTimer.Enabled = true;
        GC.KeepAlive(aTimer);
    }
    public static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        PresenceService ps = new PresenceService();
        ps.GetAbsenceContacts(); //takes 10 seconds
    }
}

さて、私の質問はPresenceService ps = new PresenceService();、タイマーが実行された後にこのクラスタイプがクリーンになっているのか、それとも GC がそれをメモリに保持しており、OnTimedEvent が実行されるたびに新しいものを開始しているのかということです。

ありがとう!

結論:コードから GC を削除します。Tnx!

4

2 に答える 2

5

さて、私の質問は、このクラスのタイプが PresenceService ps = new PresenceService(); かどうかです。タイマーが実行された後にクリーンになるか、GC がそれをメモリに保持し、OnTimedEvent が実行されるたびに新しいものを開始します。

はい。

PresenceService のインスタンスはスコープを離れるため、ガベージ コレクションの対象になります。ただし、GC はほとんど不確定であるため、再利用されるまでメモリ内に残ります。したがって、何かを実行し、ライフサイクルを持つオブジェクト (タイマーなど) では、ある種の「シャットダウン」メソッドを呼び出すとよいでしょう。

しかし、より大きな疑問は、なぜ Web アプリでタイマーを実行しているのか、またガベージ コレクターでメソッドを直接呼び出す必要があるのか​​ ということです。これは通常、アプリケーションに問題があることを示しています。

于 2013-10-03T14:15:21.827 に答える
2

インスタンスは、終了時にガベージ コレクションのps対象になります。1もちろん、これは何らかの形で (静的変数などを介して) 独自の参照をルート化しないことを前提としています。OnTimedEventPresenceService

また、GC.KeepAlive この場合は必要ありません。その理由はaTimer静的であるため、その有効期間はすでにアプリケーション ドメインに関連付けられています。つまり、静的変数によって半永久的にルート化されているためaTimer、メソッドのどの時点でもコレクションの対象になりません。Start

GC.KeepAliveGC が過度に積極的になるシナリオで使用されます。リリース構成を使用してアプリケーションをコンパイルし、デバッガーの外部で実行すると、GC はオブジェクト インスタンスがスコープ外になる前であっても、コレクションの対象としてマークします。例えばコンプリートps前でも集められるGetAbsenceContractsGC.KeepAlive基本的にその最適化をオフにします。通常、オブジェクト参照をアンマネージド API に渡すアンマネージド相互運用シナリオで使用されます。GC は管理されていない領域で何が起こっているかを何も知らないため、参照が使用されなくなったと誤って判断し、時期尚早に収集する可能性があります。


1技術的には、これは厳密には正しくありません。インスタンスが使用されなくなったと GC が判断した場合、そのインスタンスはコレクションの対象になります。それがまだスコープ内にあるかどうかとはほとんど関係がありません。

于 2013-10-03T14:26:20.627 に答える