0

私のサービスはほぼ正常に機能していますが、1日1回しか機能しないはずです。

これを調整するために、上司は明日の午前7時までワーカースレッドをスリープ状態にすることを推奨しました。

このThread.Sleep呼び出しは、明らかに機能する彼が書いた同様のサービスから直接コピーされますが、これは常にArgumentOutOfRangeExceptionをスローします-返される値は負です。

    Private Sub startExport()
#If Not Debug Then
            Thread.Sleep(1000 * 60 * 1)
#End If
        While runReportExport
            Try
                runExport()
            Catch ex As Exception
                el.WriteEntry("Error exporting data: {1}")
            Finally
                'sleep thread until tomorrow 7am
                Thread.Sleep(DateTime.Now.Subtract(Date.Today.AddDays(1).AddHours(7)))
            End Try
        End While
    End Sub

私はこれがどのように機能するかについてかなり混乱しているので、誰かが私のために全期間のことを説明することができれば、私はそれを大いに感謝します。

一方、私の友人は、スレッドの実行を別の方法で管理することを勧めています。

これが彼が私に勧めたことです:

Private lastExecute As DateTime = DateTime.Now

Private Overrides Sub OnStart(ByVal args() As String)
    startService()
End Sub

Private Sub startService()
    Dim nextExecute = lastExecute.AddDays(1)
    If nextExecute >= DateTime.Now Then
        lastExecute = DateTime.Now

        tWorker = New Thread(AddressOf startExport)
        tWorker.IsBackground = True
        tWorker.Start()
    End If
End Sub

彼は、これは起動時に一度だけワーカースレッドを実行し、別の日には再度実行しないと述べました。このコードはエラーなしで機能しますが、サービスループがワーカースレッドを繰り返し実行するのを停止しません(現在、最初の実行が終了するとすぐに2回実行されます)

個人的にはどちらのアプローチにもオープンで、どちらもうまくいかないようです。

基本的に、一日の終わりに必要なのは、1日1回データをエクスポートするサービスだけです。

上司のThread.Sleepオプションの方が簡単なようですが、友人の提案の方が良い方法のようです。

誰かが私がこれを分類するのを手伝ってくれますか(この時点では、それが機能する限り、どちらを使用してもかまいません)?

4

2 に答える 2

1
 DateTime.Now.Subtract(Date.Today.AddDays(1).AddHours(7)))

現在の時刻から将来の時刻を減算します。それは常に負の値を生成します。カブーム。

これを逆にして、将来の時刻から現在の時刻を引く必要があります。明確にし、DateTimeでのレースを回避するためにスペルアウトしました。

Dim today = DateTime.Now
Dim tomorrow = today.Date.AddDays(1).AddHours(7)
Dim wait = tomorrow - today
Thread.Sleep(wait)

サービスが停止しているときは、何か便利なことをする必要があります。ManualResetEventを使用すると、WaitOne(wait)メソッドからスリープ状態になります。ところで、スレッドをその長い間スリープさせて、何も役に立たないのは非常に無駄です。代わりにタイマーを使用してください。

于 2013-03-20T11:22:19.873 に答える
0

特定のタスクを 1 日 1 回実行するためのもう 1 つの方法 (私が使用する方法) は、タイマーでタスクを設定することです。私の場合、タスクを毎朝午前 12 時 5 分に実行したいと考えています。したがって、プログラムの開始時に、最初のティックが翌日の午前 12:05 になるようにタイマーの初期間隔を設定します。その後、1 日 1 回、ティックの一部として実行されるコードの最後で、次のティックが翌日の午前 12 時 5 分に発生するようにタイマー間隔をもう一度リセットしました。

...

Timer1.Interval = MillisecondsToMidnight() + 300000 ' next tick 12:05:00 tomorrow

...

Private Function MillisecondsToMidnight() As Integer

    Dim ReturnValue As Integer
    Dim ts As TimeSpan

    Dim Tomorrow As DateTime = Today.AddDays(1)
    ts = Tomorrow.Subtract(Now)

    ReturnValue = ts.TotalMilliseconds()

    ts = Nothing
    Return ReturnValue

End Function
于 2013-03-20T11:10:56.413 に答える