Here is a sample code of how to create a class that implement a custom backgroundworker with VB.NET 2005/2008;
Prerequisite: you have to be familiar with Delegates and Events.
1-Create a new project.
2-Right click on the project name and choose Add New Class
3-Name the class tBackgroundWorker.
4-Imports System.ComponentModel
5-Serialize this ToolboxBitmap with
Namespace AFRICTEK
Public Class BackgroundWorker : Inherits System.ComponentModel.Component
Private _CancelPending As Boolean = False
Private _ReportsProgress As Boolean = False
Private _SupportsCancellation As Boolean = False
Public Event DoWork As DoWorkEventHandler
Public Event ProgressChanged As ProgressChangedEventHandler
Public Event RunWorkerCompleted As RunWorkerCompletedEventHandler
Private Sub ProcessDelegate(ByVal delegateToProcess As System.Delegate, ByVal ParamArray args As Object())
If delegateToProcess Is Nothing Then
Exit Sub
End If
Dim delegates As System.Delegate() = delegateToProcess.GetInvocationList
For Each handler As System.Delegate In delegates
InvokeDelegate(handler, args)
Next
End Sub
Private Sub InvokeDelegate(ByVal delegateToInvoke As System.Delegate, ByVal args As Object())
Dim synchronizer As System.ComponentModel.ISynchronizeInvoke = Nothing
If GetType(System.ComponentModel.ISynchronizeInvoke).IsInstanceOfType(delegateToInvoke.Target) Then
synchronizer = DirectCast(delegateToInvoke.Target, System.ComponentModel.ISynchronizeInvoke)
End If
If Not (synchronizer Is Nothing) Then ' A windows Form object
If synchronizer.InvokeRequired = False Then
delegateToInvoke.DynamicInvoke(args)
Return
End If
Try
synchronizer.Invoke(delegateToInvoke, args)
Catch ex As Exception
End Try
Else ' Not a windows form object
delegateToInvoke.DynamicInvoke(args)
End If
End Sub
Private Sub AsyncOperationCompleted(ByVal asyncResult As IAsyncResult)
Dim doWorkEventDelegate As DoWorkEventHandler = CType(CType(asyncResult, System.Runtime.Remoting.Messaging.AsyncResult).AsyncDelegate, DoWorkEventHandler)
Dim doWorkArgs As DoWorkEventArgs = CType(asyncResult.AsyncState, DoWorkEventArgs)
Dim result As Object = Nothing
Dim doWorkEventError As Exception = Nothing
Try
doWorkEventDelegate.EndInvoke(asyncResult)
result = doWorkArgs.Result
Catch ex As Exception
doWorkEventError = ex
End Try
Dim completedArgs As RunWorkerCompletedEventArgs
completedArgs = New RunWorkerCompletedEventArgs(result, doWorkEventError, doWorkArgs.Cancel)
OnRunWorkerCompleted(completedArgs)
End Sub
Protected Overridable Sub OnRunWorkerCompleted(ByVal completedArgs As RunWorkerCompletedEventArgs)
ProcessDelegate(RunWorkerCompletedEvent, Me, completedArgs)
End Sub
Public Overloads Sub RunWorkerAsync()
RunWorkerAsync(Nothing)
End Sub
Public Overloads Sub RunWorkerAsync(ByVal argument As Object)
Me._CancelPending = False
If Not (DoWorkEvent Is Nothing) Then
Dim args As DoWorkEventArgs
If argument Is Nothing Then
argument = New Object
End If
args = New DoWorkEventArgs(argument)
Dim callback As AsyncCallback
callback = AddressOf Me.AsyncOperationCompleted
DoWorkEvent.BeginInvoke(Me, args, callback, args)
End If
End Sub
Public Overloads Sub ReportProgress(ByVal percent As Integer)
Me.ReportProgress(percent, Nothing)
End Sub
Public Overloads Sub ReportProgress(ByVal percent As Integer, ByVal userState As Object)
If WorkerReportsProgress Then
Dim progressArgs As ProgressChangedEventArgs = New ProgressChangedEventArgs(percent, userState)
OnProgressChanged(progressArgs)
End If
End Sub
Protected Overridable Sub OnProgressChanged(ByVal progressArgs As ProgressChangedEventArgs)
ProcessDelegate(ProgressChangedEvent, Me, progressArgs)
End Sub
Public Sub CancelAsync()
If Me._SupportsCancellation = True Then
SyncLock Me
Me._CancelPending = True
End SyncLock
Else
Throw New System.InvalidOperationException("This BackgroundWorker states that it doesn't support cancellation. Modify WorkerSupportsCancellation to state that it does support cancellation.")
End If
End Sub
Public ReadOnly Property CancellationPending() As Boolean
Get
SyncLock Me
Return Me._CancelPending
End SyncLock
End Get
End Property
Public Property WorkerSupportsCancellation() As Boolean
Get
SyncLock Me
Return Me._SupportsCancellation
End SyncLock
End Get
Set(ByVal Value As Boolean)
SyncLock Me
Me._SupportsCancellation = Value
End SyncLock
End Set
End Property
Public Property WorkerReportsProgress() As Boolean
Get
SyncLock Me
Return Me._ReportsProgress
End SyncLock
End Get
Set(ByVal Value As Boolean)
SyncLock Me
Me._ReportsProgress = Value
End SyncLock
End Set
End Property
End Class
Public Class DoWorkEventArgs : Inherits System.ComponentModel.CancelEventArgs
Private _Result As Object
Public Property Result() As Object
Get
Return Me._Result
End Get
Set(ByVal Value As Object)
Me._Result = Value
End Set
End Property
Public ReadOnly Argument As Object
Public Sub New(ByVal argument As Object)
Me.Argument = argument
End Sub
End Class
Public Class ProgressChangedEventArgs : Inherits EventArgs
Public ReadOnly ProgressPercentage As Integer
Public ReadOnly userState As Object
Public Sub New(ByVal percentage As Integer, ByVal userState As Object)
Me.ProgressPercentage = percentage
Me.userState = userState
End Sub
End Class
Public Class AsyncCompletedEventArgs : Inherits EventArgs
Public ReadOnly [Error] As Exception = Nothing
Public ReadOnly Cancelled As Boolean
Public ReadOnly UserState As Object
Public Sub New(ByVal runException As Exception, ByVal cancel As Boolean, ByVal userState As Object)
Me.Error = runException
Me.Cancelled = cancel
Me.UserState = userState
End Sub
Protected Sub RaiseExceptionIfNecessary()
If Me.Cancelled = True Then
Throw New System.InvalidOperationException("Operation has been cancelled.")
End If
If Not Me.Error Is Nothing Then
Throw New InvalidCastException
End If
End Sub
End Class
Public Class RunWorkerCompletedEventArgs : Inherits AsyncCompletedEventArgs
Public ReadOnly Property Result() As Object
Get
Me.RaiseExceptionIfNecessary()
Return Me.UserState
End Get
End Property
Public Sub New(ByVal result As Object, ByVal runException As Exception, ByVal cancel As Boolean)
MyBase.New(runException, cancel, result)
End Sub
End Class
Public Delegate Sub DoWorkEventHandler(ByVal sender As Object, ByVal e As DoWorkEventArgs)
Public Delegate Sub ProgressChangedEventHandler(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
Public Delegate Sub RunWorkerCompletedEventHandler(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
End Namespace
1 comment:
How would you get the results from this call back to the main program?
Post a Comment