0

MSSQLおよびPostrgeSQLデータベースからデータを取得して、定期的に(1時間ごとに)MySQLデータベースにデータを入力しようとしています。

私が行った調査に基づいて、C#タイマーを使用してそれを実行したいと思います。しかし、私はタイマーがどのように機能するかを完全には理解していません。Page_Loadで宣言し、経過したイベントハンドラーを設定し、イベントハンドラーからメソッドを呼び出します。

protected void Page_Load(object sender, EventArgs e)
{
    int duration = 100 * 60 * 5; //milliseconds * seconds * minutes

    // Create a timer with a two second interval.
    System.Timers.Timer timer = new System.Timers.Timer(duration);

    // Hook up the Elapsed event for the timer.
    timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);

    timer.Enabled = true;
}

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    cf();
}

これは機能しますが...

問題は、この方法では、ページがロードされるたびにタイマーが初期化されることです。一度だけ初期化され、再初期化されずにその瞬間から実行し続けるタイマーを作成するにはどうすればよいですか。また、タイマーまたはメソッドが失敗した場合、例外をスローした場合、またはサーバーがダウンした場合、どのように対処すればよいですか?その後、タイマーを再起動するにはどうすればよいですか?

どんな洞察も役に立ちます!前もって感謝します!

4

5 に答える 5

2

ASP.NETWebページでこれを実行する必要はありません。ASP.NETタイマーは、ページを移動する前に、ページの存続期間中にアクションが発生するように設計されています。

このような長時間の作業(つまり、24時間年中無休で1時間に1回のタスク)を実行したい場合は、次のいずれかを使用する方がはるかに良いでしょう。

  • System.Timerまたは
  • 1時間に1回のスケジュールでWindowsのスケジュールされたタスクを使用します。これにより、コンソールアプリケーションが開始されます。

別のオプションは、タスクがデータベースデータ転送に大きく関連しているように見えるため、SSISまたは別の代替ETLツール(Extract-Transform-Load)などを使用することです。

于 2012-04-17T21:36:53.620 に答える
1

他の答えはこれに触れています。頭を悩ませます。ASP.NETのタイマーは悪い考えです。

ASP.NETのライフサイクルに関係している理由。非常に短いのは、Pageクラスのインスタンス(コードビハインド)がページの読み込みごとにインスタンス化されることです。結果のページがHTMLとしてクライアントのブラウザに出力されると、Pageインスタンスはスコープを離れ、破棄されます。つまり、今から1時間後に実行するように設定されたタイマーは、Tickイベントが発生する前に長く消えてしまいます。単純なページの場合、Pageクラスは1秒未満メモリに保持できます。

場合によっては、タイマーをセッションに保存することでこれを回避できます。このタイマーは、ユーザーがサイトに接続している限り存続します。ただし、セッションは通常1時間よりもはるかに早くタイムアウトします(15分が一般的な標準です。オンライン銀行アプリのように大量のプライベートデータがあるサイトでは、5分ほどでタイムアウトします)。

したがって、繰り返しますが、ASP.NETコードではタイマーを使用しないでください。代わりに、このデータプルを1時間ごとに実行するWebサーバー(またはアプリサーバー)で実行されているWindowsサービスでタイマーを使用できます。おそらくASP.NETがオンラインユーザーアカウントを認証/承認するために使用するデータベースにアクセスすることにより、接続しているユーザーなどの情報をWebアプリケーションから提供できます。

単にデータの更新を行うWebアプリでなければならない場合は、次にデータをプルする必要があることを示す非表示フィールドまたはJavaScript変数をページのどこかに保持します。ドキュメントが読み込まれるときにJavaScriptのtimeout()を設定します。これにより、サーバーへのAJAX呼び出しがトリガーされ、他の2つのDBからのデータでMySqlを更新するイベントハンドラーが実行されます。このデータの更新が実際にコードビハインドで行われることになっていることを常に確認してください(おそらくSessionまたはViewStateで同じ値を維持することによって)。そうでない場合は、FireBugやChromeのビルドなどのプラグインを使用して自分のページのコードをDoSメカニズムに変換するのは簡単です。 -コードエディタで。更新の時間が経過した場合は、Page_Loadから同じイベントを発生させることもできます。これにより、ユーザーがJavaScriptを無効にしている場合に自分自身をカバーできます。

于 2012-04-17T21:49:13.417 に答える
0

コンソールアプリケーション、Windowsサービス、またはタスクをスケジュールするためのローカルシステムにアクセスできないことによって制限されていると仮定した場合の1つのオプションは、次のことです。タイマーが利用できない場合のシミュレートされたタイマーの私のソリューション。

また、タイマーが正確に正時に発火する必要はないと想定する必要があります。

  1. タイマージョブが最後に実行された時刻をログに記録するテーブルをデータベースに追加します。
  2. ページの読み込みが完了したら、最後にタイマージョブを実行してから1時間経過しているかどうかを確認します。
  3. 1時間以上経過した場合は、その時点でタイムジョブを実行します。
  4. タイムジョブが開始されると、開始されたデータベースにログが記録されるため、別のジョブが開始されなくなります。

これは、他のオプションがない場合にタイマーをシミュレートするための非常に奇抜な方法であることに注意してください。

于 2012-04-18T03:19:35.340 に答える
0

Global.asaxでタイマーを初期化します。OnApplicationStartメソッド..http : //msdn.microsoft.com/en-us/library/1xaas8a2(v = vs.71).aspx

同様のアプローチがここで説明されています: http ://www.west-wind.com/weblog/posts/2007/May/10/Forcing-an-ASPNET-Application-to-stay-alive

于 2012-04-17T21:37:14.157 に答える
0

初期化子を移動したい最初のことは、他のすべての変数を宣言することでした。次に、ページに、間隔時間を次の1時間に到達するのにかかる時間に設定する関数をロードさせることができます。これが私がしたことです。

    private void SetTimer()
    {
        timer1.Stop();
        var timeOfDay = DateTime.Now.TimeOfDay;
        var nextFullHour = TimeSpan.FromHours(Math.Ceiling(timeOfDay.TotalHours));
        var delta = (nextFullHour - timeOfDay).TotalMilliseconds;
        timer1.Interval = (int)delta;
        timer1.Start();
    }

シナリオが少し異なるかもしれませんが、それは少し役立つかもしれません。

于 2012-04-17T21:37:23.857 に答える