-1

Webサービスが稼働しているかどうかを確認するためのビジネスロジックがあります。

開始時刻から1時間、5分おきに繰り返し確認したい。

タスクまたはスレッドまたはawait/async機能を介してこれを行う方法。

4

2 に答える 2

5

スレッド ソリューションは次のようになります。

public class WebserviceChecker {

    private int durationInHours = 1;
    public void setDuration(int value) { durationInHours = value; }

    private boolean _shutdown = false;

    private DateTime _startTime = null;
    // System.Windows.Forms.Timer
    private Timer _timer = null;

    public void CheckWebservice() {

        _startTime = DateTime.Now;
        _timer = new Timer();
        _timer.Tick += handleTimerTick;

        while(!_shutdown) {
            try {
                // do what ever you want to do for checking your webservice...
                // ...
            } catch (ThreadAbortedException ex) {
                // do cleanup, then
                //
                break;
            } catch (Exception ex) {
                Logger.Instance.log(LoggerLogType.Type.Err, ex.ToString());
            }
            // wait 5 secs (customize to your needs)
            Threading.Thread.Sleep(5000);
        }

        if(_shutdown) {
            // do some regular cleanup here...
        }

    } // public void CheckWebservice()

    public void Shutdown() {
        _shutdown = true;
    }

    private void handleTimerTick(Object sender, System.EventArgs e) {
        TimeSpan ts = _startTime .Subtract(DateTime.Now);
        if(ts.TotalHours >= durationInHours) {
            Shutdown();
        }
    }
}

次に、次のようにバックグラウンド スレッドを開始します。

WebserviceChecker _c = new WebserviceChecker();

Thread _watcher = new Thread(_c.CheckWebservice);
_watcher.IsBackground = true;
_watcher.Start();

スケジュールされたタスクについては、こちらをご覧ください: C# スケジュールされたタスクを開始する

外部プロセスからデータを取得するのはもう少し複雑なので、スレッドソリューションをお勧めします。スレッド データをメイン スレッドに同期する方が簡単です。名前付きパイプまたはソケット通信 (TCP/UDP) によるWCF上の IPC (プロセス間通信) のようなパラダイムが必要です。

スレッドからデータを取得する方法のヒントが必要な場合: たとえば、WS の状態が変化したときに発生する WebserviceChecker クラスでイベントを定義できます。

IsBackgroundについてのいくつかの言葉...スレッドをバックグラウンドに設定しない場合、アプリケーションはすべてのフォアグラウンド スレッドがワーカー メソッドを終了したときにのみ終了します。アプリケーションがシャットダウンすると、バックグラウンド スレッドは自動的に中止されます。

ThreadAbortedException について一言: .NET では、スレッドをハード アボートする特権を取得します。フレームワークは、スレッド メソッドの任意の位置でこの例外を発生させて終了します。キャッチしないと、スレッドはクリーンアップせずに終了します。キャッチして、メモリをクリーンアップするか、いくつかの仕上げタスクを実行してください。ここでは次のようにします。

_watcher.Abort();

乾杯セス:)

[編集] MSDN に優れたマルチスレッド チュートリアルがあります: http://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspx [/編集]

[編集] System.Threading.Timer を使用する場合は、System.Threading.TimerCallback デリゲートをウォッチャー クラスに実装する必要があります。その後、バックグラウンド スレッドの代わりに期間を使用して新しいタイマーをインスタンス化できます。詳細については、 http://msdn.microsoft.com/de-de/library/system.threading.timercallback.aspxを参照してください [/edit]

于 2013-03-08T06:51:22.137 に答える
1

まず、ビジネス要件を再検討します。これは正確に何を得るのですか?Web サービスはいつでも突然なくなる可能性があるため、チェックしたからといって、次の呼び出しが成功するとは限りません。これは、すべてのネットワーク通信に当てはまります。

したがって、別の「チェッカー」を使用しても、「実際の」コードの複雑さは軽減されません。この種の設計の唯一の利点は、サービスへの次の呼び出しが成功することを合理的に確信できるユーザーへの視覚的な通知です。それでも、再考する必要があるかもしれません。なぜなら、それは合理的に確実であり、嘘をつくとユーザーは怒るからです。

Taskつまり、次のように sを使用して実行できます。

private static async Task CheckAsync(CancellationToken token)
{
  // Check your web service.
  await CheckWebServiceAsync(token);

  // Wait 5 minutes.
  await Task.Delay(TimeSpan.FromMinutes(5), token);
}

...

var done = new CancellationTokenSource(TimeSpan.FromHours(1));
Task checkingTask = CheckAsync(done.Token);
// When checkingTask completes:
//   IsCanceled -> One hour passed with no errors.
//   IsFaulted -> The web service failed.
于 2013-03-08T13:37:30.567 に答える