Задания выполняются в фоновом режиме, ожидание времени может быть прервано в любой момент.
Само задание представляет из себя процедуру, принимающую в качестве аргумента переменную типа object.
Методы:
Start(nDuration). Запускает цикл с таймером.
Stop. Если поток не выполняет задание, останавливает цикл с таймером. Если поток в данный момент выполняет задание, ждет WaitForAbortTimeout милисекунд, после чего принудительно завершает поток с заданием(если задать WaitForAbortTimeout=-1 то принудительного заврешения не будет).
ErrorHandler. Если это свойство задано, то процедура, указанная в нем вызывается в случае если выполнение задания завершается ошибкой.
Код:
- Код: Выделить всё
Namespace lae.Synchronization
Public Class Task
Public Delegate Sub TaskSub(ByVal nObject As Object)
Public Delegate Sub ErrorHandlerSub(ByVal nException As Exception, ByVal nTask As TaskSub, ByVal nTaskObject As Object)
Dim mTask As TaskSub
Dim mTaskObject As Object
Dim mDuration As UInteger
Dim mThread As New Threading.Thread(AddressOf ThrdRoutine)
Dim mCleanAbortEvent As New Threading.ManualResetEvent(False)
Dim mLockObject As New Object
Dim mErrorHandler As ErrorHandlerSub
Public WaitForAbortTimeout As Integer = 10000
Public Sub New(ByVal nTask As TaskSub, ByVal nTaskObject As Object)
'Важно! В дальнейщем эти объекты(Task и TaskObject уже не должны меняться)
If nTask Is Nothing Then
Throw New ArgumentNullException
Else
mTask = nTask
mTaskObject = nTaskObject
mThread.Priority = Threading.ThreadPriority.BelowNormal
End If
End Sub
Public Sub Start(ByVal nDuration As UInteger)
If nDuration < 100 Then Throw New ArgumentException
SyncLock mLockObject
If mDuration = 0 Then
mDuration = nDuration
mThread.Start()
Else
Throw New InvalidOperationException
End If
End SyncLock
End Sub
Public Sub [Stop]()
SyncLock mLockObject
If mDuration = 0 Then Exit Sub
mCleanAbortEvent.Set()
If Not mThread.Join(WaitForAbortTimeout) Then
mThread.Abort()
End If
mDuration = 0
mCleanAbortEvent.Reset()
End SyncLock
End Sub
Private Sub ThrdRoutine()
Do
If mCleanAbortEvent.WaitOne(mDuration, False) Then
Return
End If
Try
mTask(mTaskObject)
Catch ex As Exception
Dim nErrorHandler As ErrorHandlerSub = mErrorHandler
If Not nErrorHandler Is Nothing Then
nErrorHandler(ex, mTask, mTaskObject)
End If
End Try
Loop
End Sub
Public Property ThreadPriority() As Threading.ThreadPriority
Get
Return mThread.Priority
End Get
Set(ByVal value As Threading.ThreadPriority)
mThread.Priority = value
End Set
End Property
Public Property ErrorHandler() As ErrorHandlerSub
Get
Return mErrorHandler
End Get
Set(ByVal value As ErrorHandlerSub)
mErrorHandler = value
End Set
End Property
End Class
End Namespace