' ******************************************************************************
' **
' ** Yahoo Finance Managed
' ** Written by Marius Häusler 2010
' ** It would be pleasant, if you contact me when you are using this code.
' ** Contact: YahooFinanceManaged@gmail.com
' ** Project Home: http://code.google.com/p/yahoo-finance-managed/
' **
' ******************************************************************************
' **
' ** Copyright 2010 Marius Häusler
' **
' ** Licensed under the Apache License, Version 2.0 (the "License");
' ** you may not use this file except in compliance with the License.
' ** You may obtain a copy of the License at
' **
' ** http://www.apache.org/licenses/LICENSE-2.0
' **
' ** Unless required by applicable law or agreed to in writing, software
' ** distributed under the License is distributed on an "AS IS" BASIS,
' ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
' ** See the License for the specific language governing permissions and
' ** limitations under the License.
' **
' ******************************************************************************
Namespace Base
''' <summary>
''' Base class for downloading data
''' </summary>
''' <remarks>This class can not be instanced outside of the library</remarks>
Public MustInherit Class Download
Friend Event AsyncBaseDownloadCompleted(ByVal sender As Download, ByVal ba As BaseDownloadCompletedEventArgs)
Private mWebClients As New List(Of TimeoutWebClient)
Private mTimeout As Integer = 30000
Private mProxy As IWebProxy = WebProxy.GetDefaultProxy
Private mGuiThread As System.Windows.Forms.Control
''' <summary>
''' The user arguments of each download process
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property UserArgs() As Object()
Get
Dim lst As New List(Of Object)
For Each wc As TimeoutWebClient In mWebClients
Dim ea As DownloadEventArgs = TryCast(wc.Args, DownloadEventArgs)
If ea IsNot Nothing Then
lst.Add(ea.UserArgs)
Else
lst.Add(wc.Args)
End If
Next
Return lst.ToArray
End Get
End Property
Public ReadOnly Property UserArgs(ByVal index As Integer) As Object
Get
If index < 0 Or index > mWebClients.Count - 1 Then
Throw New IndexOutOfRangeException("The index is out of download list range.")
Else
Return Me.GetUserObject(mWebClients(index).Args)
End If
End Get
End Property
''' <summary>
''' Gets or sets the timeout of the next asynchronous download. If value is 0(zero), the next download wont have a timeout.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Timeout() As Integer
Get
Return mTimeout
End Get
Set(ByVal value As Integer)
If value >= 0 Then : mTimeout = value
Else : mTimeout = 0
End If
End Set
End Property
''' <summary>
''' Gets or sets the used Proxy informations.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Proxy() As IWebProxy
Get
Return mProxy
End Get
Set(ByVal value As IWebProxy)
mProxy = value
End Set
End Property
''' <summary>
''' The number of running asynchronous downloads.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property AsyncDownloadsCount() As Integer
Get
Return mWebClients.Count
End Get
End Property
Friend Function Download(ByVal url As String) As TimeoutWebClientResponse
Try
Dim str As IO.Stream = Nothing
Using wc As New TimeoutWebClient(mGuiThread)
wc.Timeout = mTimeout
If mProxy IsNot Nothing Then wc.Proxy = mProxy
Dim resp As TimeoutWebClientResponse = wc.Download(url)
Return resp
End Using
Catch ex As Exception
Return New TimeoutWebClientResponse(New ConnectionInfo(New Net.WebException("Unkonown Error occured", ex, WebExceptionStatus.UnknownError, Nothing), mTimeout, 0, Date.Now), Nothing)
End Try
End Function
Friend Sub DownloadAsync(ByVal url As String, ByVal args As Object)
Dim wc As New TimeoutWebClient(mGuiThread) With {.Timeout = mTimeout}
If mProxy IsNot Nothing Then wc.Proxy = mProxy
AddHandler wc.AsyncDownloadCompleted, AddressOf Me.AsyncDownload_Completed
mWebClients.Add(wc)
wc.DownloadAsync(url, args)
End Sub
''' <summary>
''' Cancels all running downloads.
''' </summary>
''' <remarks></remarks>
Public Function CancelAsyncAll() As Boolean
If mWebClients.Count > 0 Then
For i As Integer = mWebClients.Count - 1 To 0 Step -1
Me.RemoveClient(mWebClients(i))
Next
End If
Return mWebClients.Count = 0
End Function
''' <summary>
''' Cancels a specific running download.
''' </summary>
''' <param name="userArgs">The user argument that the download object contains.</param>
''' <returns></returns>
''' <remarks></remarks>
Public Function CancelAsync(ByVal userArgs As Object) As Integer
If mWebClients.Count > 0 Then
Dim count As Integer = 0
For i As Integer = mWebClients.Count To 0 Step -1
If Me.ArgsEqual(mWebClients(i).Args, userArgs) Then
Me.RemoveClient(mWebClients(i))
count += 1
End If
Next
Return count
Else
Return 0
End If
End Function
''' <summary>
''' Cancels a specific running download.
''' </summary>
''' <param name="index">The position of the download process in queue.</param>
''' <returns></returns>
''' <remarks></remarks>
Public Function CancelAsyncAt(ByVal index As Integer) As Boolean
Return Me.RemoveClient(mWebClients(index))
End Function
''' <summary>
''' Returns the number of download processes with the passed user argument.
''' </summary>
''' <param name="userArgs"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function Contains(ByVal userArgs As Object) As Integer
Dim count As Integer = 0
For Each wc As TimeoutWebClient In mWebClients
If Me.ArgsEqual(wc.Args, userArgs) Then count += 1
Next
Return count
End Function
Private Sub AsyncDownload_Completed(ByVal sender As TimeoutWebClient, ByVal ea As TimeoutWebClientDownloadCompletedEventArgs)
Try
If mWebClients.Contains(sender) Then mWebClients.Remove(sender)
RaiseEvent AsyncBaseDownloadCompleted(Me, New BaseDownloadCompletedEventArgs(ea.UserArgs, ea.Response))
Catch ex As Exception
Finally
Me.RemoveClient(sender)
End Try
End Sub
Private Function RemoveClient(ByVal wc As TimeoutWebClient) As Boolean
If wc IsNot Nothing Then
RemoveHandler wc.AsyncDownloadCompleted, AddressOf AsyncDownload_Completed
If wc.IsBusy Then wc.CancelAsync()
wc.Dispose()
If mWebClients.Contains(wc) Then Return mWebClients.Remove(wc)
End If
Return False
End Function
Private Function ArgsEqual(ByVal argsX As Object, ByVal argsY As Object) As Boolean
If argsX IsNot Nothing And argsY IsNot Nothing Then
Return Me.GetUserObject(argsX) Is Me.GetUserObject(argsY)
Else : Return True
End If
End Function
Private Function GetUserObject(ByVal args As Object) As Object
Return IIf(TypeOf args Is DownloadEventArgs, DirectCast(args, DownloadEventArgs).UserArgs, args)
End Function
Friend Sub New()
mGuiThread = New System.Windows.Forms.Control
mGuiThread.CreateControl()
End Sub
End Class
Friend Class BaseDownloadCompletedEventArgs
Inherits DownloadCompletedEventArgs
Public Overloads ReadOnly Property Response() As TimeoutWebClientResponse
Get
Return DirectCast(MyBase.Response, TimeoutWebClientResponse)
End Get
End Property
Public Sub New(ByVal userArgs As Object, ByVal response As TimeoutWebClientResponse)
MyBase.New(userArgs, response)
End Sub
End Class
End Namespace