2

Windows サービス (ローカル システムで実行) でホストされている WCF サービスがあります。その中で System.Timer を実行しています。Timer を初期化するOperation o1は、webHttpBinding を介して http エンドポイントで宣言されます。System.ServiceModel のトレースを有効にし、.svcLog ファイルから操作 o1 のリッスン期間を確認しました。約 20 時間実行した後、http エンドポイントでのリッスンが停止したことを示しています。

これは、着信メッセージがそのエンドポイントに到着しなかったためだと思います。ここでの問題は、リスニングが停止することであり、タイマー (その特定の操作o1内で初期化されたもの) も停止します!

リスナー、つまりタイマーを長時間維持するための推奨される方法はありますか? o1 操作を定期的に ping してメモリに保持できますか?

また、オペレーション o1 内で初期化するタイマー変数はインスタンス変数ですが、この変数はリスナーが閉じてもメモリ内にあると予想されません (WCF はシングルトンです)。

本当にありがとう。

コードの抜粋-

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public class SchedulerWindows : ISchedulerWindows
{
    ///.........all instance variables.....
    DataTimer timer = null; /**DataTimer wraps a System.Timers timer variable**/
    public List<DataTimer> timersInService = new List<DataTimer>();
    public ISchedulerWindows.o1(string s1, string s2, /*********/)
    {
     //..........//
     timer = new DataTimer();
    }
}

public class DataTimer
    {

        /****Newly introduced System.Threading.Timer, previously I was using        System.Timers.Timer which was dying****/

        public System.Threading.Timer thTimer;
        private static readonly object dbAccessLock = new object();
        private static readonly object thCallbackLock = new object();

        public DataTimer()
        {
        }

        public DataTimer(/************/)
        {            
            TimerCallback timerDelegate = new TimerCallback(this.WorkMethod);
            EventLogLogger l = new EventLogLogger();
            //l.LogMessage("setting up timer ");
            thTimer = new Timer(this.WorkMethod, null, 0, period);
        }
...
}

編集:System.Timers名前空間からSystem.Threading名前空間に変更し、時間間隔を長くすると、修正されました。タイマー変数はもう消えません。

4

2 に答える 2

1

問題の最も可能性の高い原因はInstanceContextModeです。サービス インスタンスを常にメモリ内に置きたい場合は、Single を使用する必要があります。おそらく PerSession または PerCall があり、タイマーが消えている理由を説明できます。あなたのサービスはシングルトンですが、症状は非常に疑わしいと述べています。ホストをシャットダウンするまで、サービス インスタンスはメモリ内に残ります。

[ServiceBehavior(
         ConcurrencyMode = ConcurrencyMode.Multiple, 
         InstanceContextMode = InstanceContextMode.Single
)]

WCF インスタンス管理から:

シングルトン サービスは永久に存続し、ホストがシャットダウンしたときにのみ破棄されます。シングルトンは、ホストの作成時に一度だけ作成されます。

編集:おそらく、リスナーがリッスンを停止し、タイマーが消えたときに、Windows サービスがまだ実行されていることを確認しました。ServiceHost 自体がメモリに残っているかどうかを確認することも理にかなっています。ServiceHosts の「Closing」、「Closed」、および「Faulted」イベント ハンドラーにログを記録することもできます。

編集 2: タイマーが消えている場合は、割り当て方法を確認する必要があります。ほとんどの場合、ガベージが収集されます。ライブ オブジェクトから到達可能なインスタンス フィールドとして宣言する必要があります。絶対に確実にするために静的にしてください。あなたはのためにそれをしますDataTimerが、タイマーがどのように宣言され、内部で割り当てられるかは明確ではありませんDataTimer。いくつかのコードを投稿してください。

編集 3: 操作でタイマーを作成しないでください。操作が複数回呼び出されるとどうなりますか? 古いタイマーはどうなりますか?あなたがそれを閉じる/処分する方法がわかりません。また、DataTimer には 2 つのコンストラクターがあるようです。そのうちの1人は何もしていません。その上に、タイマーの個別のリストがあります。これは少し複雑です。問題を切り分けて、その後新しいコードを投稿してください。

于 2011-08-15T00:59:39.980 に答える