[dba-VB] inheriting events

Shamil Salakhetdinov shamil at users.mns.ru
Fri Jan 4 18:49:11 CST 2008


Hello John,

As promised yesterday - here is a solution with multi-threading based on
article I mentioned in this thread already:

http://www.yoda.arachsys.com/csharp/threads/winforms.shtml 

1. Create WinForms sample app with Form1 form
2. Create two buttons Button1 and Button2 on this form
3. Create listbox ListBox1
4. Put this code behind for Form1 and set buttons' click event properly:

Public Class Form1 : Implements IStatusDisplay

    Private Sub Button1_Click(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles Button1.Click
        ListBox1.Items.Clear()
        TestModule.MainSync(Me)
    End Sub
    Private Sub Button2_Click(ByVal sender As System.Object, _
               ByVal e As System.EventArgs) Handles Button2.Click
        ListBox1.Items.Clear()
        TestModule.MainAsync(Me)
    End Sub

    Delegate Sub StringParameterDelegate(ByVal value As String)

    Public Sub UpdateStatus(ByVal value As String) _
              Implements IStatusDisplay.UpdateStatus
        If (Me.InvokeRequired) Then
            Me.BeginInvoke(New StringParameterDelegate( _
                   AddressOf UpdateStatus), New Object() {value})
            Return
        End If
        ListBox1.Items.Add(value)
        Application.DoEvents()
    End Sub
End Class

5. put this code into Module1

Option Explicit On

Public Interface IStatusDisplay
    Sub UpdateStatus(ByVal value As String)
End Interface

Public Interface IProxyProgress
    Event EventOne(ByVal msg As String)
    Event EventTwo(ByVal msg As String, ByVal count As Integer)
End Interface

Public Interface IFileProcessor
    Sub Execute(ByVal sleepInterval As Object)
End Interface

Public Class ProxyProgress
    Implements IProxyProgress

    Protected _display As IStatusDisplay
    Public Sub New(ByVal display As IStatusDisplay)
        _display = display
    End Sub

    Private Event EventOne(ByVal msg As String) _
                   Implements IProxyProgress.EventOne

    Private Event EventTwo(ByVal msg As String, ByVal count As Integer) _
                   Implements IProxyProgress.EventTwo

    Protected Sub RaiseEventOne(ByVal msg As String, ByVal eventSource As
Type)
        Dim message As String = eventSource.ToString() + ": " + msg
        RaiseEvent EventOne(message)
        _display.UpdateStatus(message)
    End Sub

    Protected Sub RaiseEventTwo(ByVal msg As String, ByVal count As Integer,
ByVal eventSource As Type)
        Dim message As String = eventSource.ToString() + ": " + msg
        RaiseEvent EventTwo(message, count)
        _display.UpdateStatus(message + ", count=" + count.ToString())
    End Sub
End Class

Public Class FileImporter
    Inherits ProxyProgress
    Implements IFileProcessor
    Public Sub New(ByVal display As IStatusDisplay)
        MyBase.New(display)
    End Sub

    Private Sub Execute(ByVal sleepInterval As Object) _
                Implements IFileProcessor.Execute
        Dim interval As Integer = CType(sleepInterval, Integer)
        For i As Integer = 1 To 5
            RaiseEventOne("Event one", Me.GetType())
            System.Threading.Thread.Sleep(interval)
            RaiseEventTwo("Event two", i, Me.GetType())
            System.Threading.Thread.Sleep(interval)
        Next i
    End Sub

End Class

Public Class FileExporter
    Inherits ProxyProgress
    Implements IFileProcessor

    Public Sub New(ByVal display As IStatusDisplay)
        MyBase.New(display)
    End Sub
    Private Sub Execute(ByVal sleepInterval As Object) Implements
IFileProcessor.Execute
        Dim interval As Integer = CType(sleepInterval, Integer)
        For i As Integer = 1 To 5
            RaiseEventOne("Event one", Me.GetType())
            System.Threading.Thread.Sleep(500)
            RaiseEventTwo("Event two", i, Me.GetType())
            System.Threading.Thread.Sleep(500)
        Next i
    End Sub
End Class

Module TestModule
    Private Sub EventOneHandler(ByVal msg As String)
        Console.WriteLine("EventOneHandler: " + msg)
    End Sub

    Private Sub EventTwoHandler(ByVal msg As String, ByVal count As Integer)
        Console.WriteLine(String.Format("EventTwoHandler: {0}, count = {1}",
msg, count))
    End Sub

    Sub MainSync(ByVal display As IStatusDisplay)  ' Sync
        Dim list As List(Of IFileProcessor) = _
             New List(Of IFileProcessor)

        Dim fileProcessor As IFileProcessor = Nothing
        Dim proxyProgress As IProxyProgress = Nothing

        ' one
        fileProcessor = New FileImporter(display)
        proxyProgress = DirectCast(fileProcessor, IProxyProgress)
        AddHandler (proxyProgress.EventOne), AddressOf EventOneHandler
        AddHandler (proxyProgress.EventTwo), AddressOf EventTwoHandler
        list.Add(fileProcessor)
        ' two
        fileProcessor = New FileExporter(display)
        proxyProgress = DirectCast(fileProcessor, IProxyProgress)
        AddHandler (proxyProgress.EventOne), AddressOf EventOneHandler
        AddHandler (proxyProgress.EventTwo), AddressOf EventTwoHandler
        list.Add(fileProcessor)

        For Each fileProcessor In list
            fileProcessor.Execute(300)
        Next fileProcessor

        ' async test
        'MainAsync()

    End Sub

    Sub MainAsync(ByVal display As IStatusDisplay)
        Dim workers(2) As System.Threading.Thread

        Dim fileProcessor As IFileProcessor = Nothing
        Dim proxyProgress As IProxyProgress = Nothing

        ' one
        fileProcessor = New FileImporter(display)
        proxyProgress = DirectCast(fileProcessor, IProxyProgress)
        AddHandler (proxyProgress.EventOne), AddressOf EventOneHandler
        AddHandler (proxyProgress.EventTwo), AddressOf EventTwoHandler
        workers(0) = New Threading.Thread(AddressOf fileProcessor.Execute)
        ' two
        fileProcessor = New FileExporter(display)
        proxyProgress = DirectCast(fileProcessor, IProxyProgress)
        AddHandler (proxyProgress.EventOne), AddressOf EventOneHandler
        AddHandler (proxyProgress.EventTwo), AddressOf EventTwoHandler
        workers(1) = New Threading.Thread(AddressOf fileProcessor.Execute)

        workers(0).Start(200)
        workers(1).Start(1000)

    End Sub
End Module

Enjoy multi-threading! :)

If you find bugs please post fixes here.

Thanks.

--
Shamil

P.S. Notes:

1. Watch line wraps in the code above
2. I did leave Console.WriteLine(...) in the above code to see how
yesterday's console app code was refactored into winforms code - as you can
find that weren't many changes...
 
-----Original Message-----
From: dba-vb-bounces at databaseadvisors.com
[mailto:dba-vb-bounces at databaseadvisors.com] On Behalf Of jwcolby
Sent: Thursday, January 03, 2008 5:51 PM
To: dba-vb at databaseadvisors.com
Subject: Re: [dba-VB] inheriting events

Shamil,

This is in fact what I was doing (minus the interfaces).  A straight base
class with the events and methods that can be called to raise the methods.
then the process classes inherit the base class and call the methods when
they want to raise the events.


John W. Colby
Colby Consulting
www.ColbyConsulting.com 




More information about the dba-VB mailing list