1 #Region "Microsoft.VisualBasic::bbe487eb9741654e6effbb9023c014fb, Microsoft.VisualBasic.Core\ApplicationServices\Parallel\Tasks\UpdateThread.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class UpdateThread
35     
36     '         Properties: Caller, ErrHandle, Periods, Running
37     
38     '         Constructor: (+1 OverloadsSub New
39     
40     '         FunctionGetTicks, Start, ToString
41     
42     '         Sub: [Stop], __invoke, __updates, (+2 Overloads) Dispose
43     
44     
45     ' /********************************************************************************/
46
47 #End Region
48
49 Imports System.Runtime.CompilerServices
50 Imports Microsoft.VisualBasic.ComponentModel
51 Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel
52 Imports Microsoft.VisualBasic.ComponentModel.Triggers
53
54 Namespace Parallel.Tasks
55
56     ''' <summary>
57     ''' Running a specific <see cref="System.Action"/> in the background periodically.
58     ''' (比较适合用于在服务器上面执行周期性的计划任务)
59     ''' </summary>
60     Public Class UpdateThread : Inherits ICallbackInvoke
61         Implements IDisposable
62         Implements ITaskDriver
63         Implements ITimer
64
65         ''' <summary>
66         ''' Sleeps n **ms** interval
67         ''' </summary>
68         ''' <returns></returns>
69         Public Property Periods As Integer Implements ITimer.Interval
70
71         ''' <summary>
72         ''' If this exception handler is null, then when the unhandled exception occurring,
73         ''' this thread object will throw the exception and then stop working.
74         ''' </summary>
75         ''' <returns></returns>
76         Public Property ErrHandle As Action(Of Exception)
77         ''' <summary>
78         ''' 指示当前的这个任务处理对象是否处于运行状态
79         ''' </summary>
80         ''' <returns></returns>
81         Public ReadOnly Property Running As Boolean
82
83         ''' <summary>
84         ''' The caller stack name
85         ''' </summary>
86         ''' <returns></returns>
87         Public ReadOnly Property Caller As String
88
89         ''' <summary>
90         ''' Running a specific action in the background periodically. The time unit of the parameter <paramref name="Periods"/> is ms or Ticks.
91         ''' </summary>
92         ''' <param name="Periods">ms for update thread sleeps</param>
93         ''' <param name="updates"></param>
94         Sub New(Periods As Integer, updates As Action, <CallerMemberName> Optional caller$ = Nothing)
95             Call MyBase.New(updates)
96
97             Me.Running = False
98             Me.Periods = Periods
99             Me.Caller = caller
100         End Sub
101
102         Private Sub __updates()
103             Call $"Start running {Me.ToString}....".__DEBUG_ECHO
104             Do While Running
105                 Call __invoke()
106             Loop
107             Call $"{Me.ToString} thread exit...".__DEBUG_ECHO
108         End Sub
109
110         ''' <summary>
111         ''' 运行这条线程,假若更新线程已经在运行了,则会自动忽略这次调用
112         ''' </summary>
113         Public Function Start() As Integer Implements ITaskDriver.Run
114             If Running Then
115                 Return 2
116             Else
117                 _Running = True
118                 Call RunTask(AddressOf __updates)
119             End If
120
121             Return 0
122         End Function
123
124         ''' <summary>
125         ''' 停止更新线程的运行
126         ''' </summary>
127         Public Sub [Stop]() Implements ITimer.Stop
128             _Running = False
129         End Sub
130
131         Private Sub __invoke()
132 #If DEBUG Then
133             Call _execute()
134 #Else
135             Try
136                 Call _execute()
137             Catch ex As Exception
138                 If Not ErrHandle Is Nothing Then
139                     Call _ErrHandle(ex)
140                 Else
141                     Throw
142                 End If
143             Finally
144                 Call Threading.Thread.Sleep(Periods)
145             End Try
146 #End If
147         End Sub
148
149         Public Overrides Function ToString() As String
150             Dim state As String = If(Running, NameOf(Running), NameOf([Stop]))
151             Return $"[{Caller}::{state}, {Me.Periods}ms]  => {Me.CallbackInvoke.ToString}"
152         End Function
153
154         ''' <summary>
155         ''' 获取得到总的毫秒数
156         ''' </summary>
157         ''' <param name="hh"></param>
158         ''' <param name="mm"></param>
159         ''' <param name="ss%"></param>
160         ''' <returns></returns>
161         Public Shared Function GetTicks(hh As Integer, mm As IntegerOptional ss% = 0) As Integer
162             Dim hhss As Integer = hh * 60 * 60 ' 小时的秒数
163             Dim mmss As Integer = mm * 60
164             Dim ticks As Integer = (hhss + mmss + ss) * 1000
165             Return ticks
166         End Function
167
168 #Region "IDisposable Support"
169         Private disposedValue As Boolean To detect redundant calls
170
171         ' IDisposable
172         Protected Overridable Sub Dispose(disposing As Boolean)
173             If Not Me.disposedValue Then
174                 If disposing Then
175                     Call [Stop]()  ' TODO: dispose managed state (managed objects).
176                 End If
177
178                 ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
179                 ' TODO: set large fields to null.
180             End If
181             Me.disposedValue = True
182         End Sub
183
184         ' TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources.
185         'Protected Overrides Sub Finalize()
186         '    Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
187         '    Dispose(False)
188         '    MyBase.Finalize()
189         'End Sub
190
191         ' This code added by Visual Basic to correctly implement the disposable pattern.
192         Public Sub Dispose() Implements IDisposable.Dispose
193             Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
194             Dispose(True)
195             ' TODO: uncomment the following line if Finalize() is overridden above.
196             ' GC.SuppressFinalize(Me)
197         End Sub
198 #End Region
199     End Class
200 End Namespace