1 #Region "Microsoft.VisualBasic::2ae74e8246a1546f48db8bca85ea8f86, Microsoft.VisualBasic.Core\ComponentModel\DataSource\Iterator.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 Iterator
35     
36     '         Properties: GetCurrent
37     
38     '         Constructor: (+1 OverloadsSub New
39     '         FunctionToString
40     
41     '     Class Iterator
42     
43     '         Properties: Current, ReadDone
44     
45     '         Constructor: (+1 OverloadsSub New
46     
47     '         FunctionGetEnumerator, MoveNext, Read
48     
49     '         Sub: __moveNext, (+2 Overloads) Dispose, Reset
50     
51     
52     ' /********************************************************************************/
53
54 #End Region
55
56 Imports System.Runtime.CompilerServices
57 Imports System.Threading
58 Imports System.Threading.Thread
59
60 Namespace ComponentModel.DataSourceModel
61
62     ''' <summary>
63     ''' 在<see cref="Iterator"/>的基础之上所构建出来的一个泛型化的迭代器对象.
64     ''' </summary>
65     ''' <typeparam name="T"></typeparam>
66     Public Class Iterator(Of T) : Inherits Iterator
67         Implements IEnumerator(Of T)
68
69         Sub New(source As IEnumerable(Of T))
70             Call MyBase.New(source)
71         End Sub
72
73         Public ReadOnly Property GetCurrent As T Implements IEnumerator(Of T).Current
74             <MethodImpl(MethodImplOptions.AggressiveInlining)>
75             Get
76                 Return DirectCast(Current, T)
77             End Get
78         End Property
79
80         Public Overrides Function ToString() As String
81             Return Scripting.ToString(Current)
82         End Function
83     End Class
84
85     ''' <summary>
86     ''' Implements for the <see cref="IEnumerable(Of T)"/>, Supports a simple iteration over a non-generic collection.
87     ''' (这个迭代器对象主要是用在远程数据源之中的,对于本地的数据源而言,使用这个迭代器的效率太低了,但是对于远程数据源而言,由于存在网络延迟,所以这个迭代器的效率影响将可以被忽略不计)
88     ''' </summary>
89     Public Class Iterator : Implements IEnumerator
90         Implements IDisposable
91
92         ReadOnly _source As IEnumerable
93
94         Sub New(source As IEnumerable)
95             _source = source
96             Reset()
97         End Sub
98
99         ''' <summary>
100         ''' Gets the current element in the collection.
101         ''' </summary>
102         ''' <returns></returns>
103         Public ReadOnly Property Current As Object Implements IEnumerator.Current
104         ''' <summary>
105         ''' Indicates that there are no more characters in the string and tokenizer is finished.
106         ''' </summary>
107         ''' <returns></returns>
108         Public ReadOnly Property ReadDone As Boolean = False
109
110         ''' <summary>
111         ''' Exposes an enumerator, which supports a simple iteration over a non-generic collection.To
112         ''' browse the .NET Framework source code for this type, see the Reference Source.
113         ''' </summary>
114         ''' <returns></returns>
115         Public Function GetEnumerator() As IEnumerable
116             Return _source
117         End Function
118
119         Dim receiveDone As New ManualResetEvent(False)
120
121         Private Sub __moveNext()
122             _ReadDone = False
123             _started = True
124
125             Single thread safely
126             For Each x As Object In _source ' 单线程安全
127                 Call receiveDone.WaitOne()
128                 Call receiveDone.Reset()
129
130                 _Current = x
131             Next
132
133             _started = False
134             _ReadDone = True
135         End Sub
136
137         ''' <summary>
138         ''' Returns current and then automatically move to next position
139         ''' </summary>
140         ''' <returns></returns>
141         Public Function Read() As Object
142             Dim x As Object = Current
143             Call MoveNext()
144             Return x
145         End Function
146
147         Dim _forEach As Thread
148         Dim _started As Boolean = False
149
150         ''' <summary>
151         ''' Sets the enumerator to its initial position, which is before the first element in the collection.
152         ''' </summary>
153         Public Sub Reset() Implements IEnumerator.Reset
154             If Not _forEach Is Nothing Then  ' 终止这条线程然后再新建
155                 Call _forEach.Abort()
156             End If
157
158             _Current = Nothing
159             _started = False
160             _ReadDone = False
161             _forEach = New Thread(AddressOf __moveNext)
162             _forEach.Start()
163
164             Do While _started = False
165                 Call Thread.Sleep(1)
166             Loop
167         End Sub
168
169         ''' <summary>
170         ''' Advances the enumerator to the next element of the collection.
171         ''' </summary>
172         ''' <returns>
173         ''' true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
174         ''' </returns>
175         Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
176             If ReadDone Then  ' 在移动之前已经读取完毕了
177                 _Current = Nothing
178                 Return False
179             End If
180
181             Call receiveDone.Set()
182             Call Thread.Sleep(1)
183
184             If ReadDone Then
185                 Return False
186             Else
187                 Return Not ReadDone
188             End If
189         End Function
190
191 #Region "IDisposable Support"
192         Private disposedValue As Boolean To detect redundant calls
193
194         ' IDisposable
195         Protected Overridable Sub Dispose(disposing As Boolean)
196             If Not Me.disposedValue Then
197                 If disposing Then
198                     ' TODO: dispose managed state (managed objects).
199                     Call _forEach.Abort()
200                     Call _forEach.Free
201                 End If
202
203                 ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
204                 ' TODO: set large fields to null.
205             End If
206             Me.disposedValue = True
207         End Sub
208
209         ' TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources.
210         'Protected Overrides Sub Finalize()
211         '    Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
212         '    Dispose(False)
213         '    MyBase.Finalize()
214         'End Sub
215
216         ' This code added by Visual Basic to correctly implement the disposable pattern.
217         Public Sub Dispose() Implements IDisposable.Dispose
218             Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
219             Dispose(True)
220             ' TODO: uncomment the following line if Finalize() is overridden above.
221             ' GC.SuppressFinalize(Me)
222         End Sub
223 #End Region
224     End Class
225 End Namespace