1 #Region "Microsoft.VisualBasic::0bdfccf401415fc73cab5664ce37567a, Microsoft.VisualBasic.Core\ApplicationServices\Parallel\Tasks\Actor(Of T, V).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 Actor
35     
36     
37     '         Delegate Sub
38     
39     '             Sub: Perform
40     '         Class State
41     
42     '             Properties: [error], parameter, result
43     
44     '             Constructor: (+1 OverloadsSub New
45     '             Sub: Run
46     
47     
48     
49     
50     
51     ' /********************************************************************************/
52
53 #End Region
54
55 Imports System.Threading
56
57 Namespace Parallel.Tasks
58
59     ''' <summary>
60     ''' This Actor class can be used to call a function which has one 
61     ''' parameter, object (T) and returns the result, object (V). The 
62     ''' result is returned in a delegate.
63     ''' </summary>
64     ''' <typeparam name="T">Input type</typeparam>
65     ''' <typeparam name="V">Output type</typeparam>
66     Public Class Actor(Of T, V)
67
68         Public Delegate Sub WhenComplete(sender As Object, e As State)
69
70         Public Overridable Sub Perform(job As Func(Of T, V), parameter As T, done As WhenComplete)
71             Dim task = Sub(x)
72                            Dim state As State = TryCast(x, State)
73                            Call state.Run()
74                            If the calling application neglected to provide a WhenComplete delegate
75                            ' check if null before attempting to invoke.
76                            Call done?.Invoke(Me, state)
77                        End Sub
78
79             ' ThreadPool.QueueUserWorkItem takes an object which represents the data
80             ' to be used by the queued method in WaitCallback.  I'm using an anonymous 
81             ' delegate as the method in WaitCallback, and passing the variable state 
82             ' as the data to use.  When a thread becomes available the method will execute.
83             ThreadPool.QueueUserWorkItem(task, New State(job, parameter))
84         End Sub
85
86         ' Waitcallback requires an object, lets create one.
87         Public Class State
88
89             ''' <summary>
90             ''' This is the parameter which is passed to the function
91             ''' defined as job.
92             ''' </summary>
93             Public Property parameter() As T
94
95             ''' <summary>
96             ''' This will be the response and will be sent back to the 
97             ''' calling thread using the delegate (a).
98             ''' </summary>
99             Public Property result() As V
100
101             ''' <summary>
102             ''' Actual method to run.
103             ''' </summary>
104             Private job As Func(Of T, V)
105
106             ''' <summary>
107             ''' Capture any errors and send back to the calling thread.
108             ''' </summary>
109             Public Property [error]() As Exception
110
111             Public Sub New(j As Func(Of T, V), param As T)
112                 job = j
113                 parameter = param
114             End Sub
115
116             Const NullException$ = "A value passed to execute is null. Check the response to determine the value."
117
118             ''' <summary>
119             '''  Set as an internal types void so only the Actor class can  
120             '''  invoke this method.
121             ''' </summary>
122             Friend Sub Run()
123                 Try
124                     ' I think I should check if the method or parameter is null, and react 
125                     ' accordingly.  I can check both values at once and throw a null 
126                     ' reference exception.
127                     If job Is Nothing Or parameter Is Nothing Then
128                         Throw New NullReferenceException(State.NullException)
129                     End If
130
131                     result = job(parameter)
132                 Catch e As Exception
133                     [error] = e
134                     result = Nothing
135                 End Try
136             End Sub
137         End Class
138     End Class
139 End Namespace