[dba-VB] VB.Net - Proxy Class

Shamil Salakhetdinov shamil at users.mns.ru
Fri Jul 27 12:56:14 CDT 2007


Hello John,

Beware! - you're entering tricky world of threads, events and delegates (you
never know what happens next in this world I mean). Be especially careful
with sending notification to the form (thread) from worker processes - as
Charlotte noted here System.ComponentModel.BackgroundWorker is the most safe
solution for this case while you're getting through learning curve....


Sample code without using System.ComponentModel.BackgroundWorker  and not
tested with WinForms - just use VB.NET console application to run it (watch
line wraps):
============

Imports System.Threading
Imports System.Collections.Generic

Module SSTestOfEventsAndDelegates
    ' // Delegate declaration
    Public Delegate Sub TestEventDelegate(ByVal objectId As Long, ByVal
msgId As Integer)

    ' // main object (form simulator)
    Public Class TestForm
        Private WithEvents _proxy _
                As New TestProcessEventsProxy()

        Private _testCount As Integer = 0
        Private Sub _proxy_TestEvent(ByVal objectId As Long, ByVal msgId As
Integer) _
                                  Handles _proxy.TestEvent
            Console.WriteLine("TestForm: Message {0}.{1} arrived.", msgId,
objectId)
            _testCount += 1
        End Sub

        Public Sub Test()
            _proxy.Test()

            Dim startTime As DateTime = DateTime.Now
            Dim ts As TimeSpan = TimeSpan.MinValue
            Dim currentTime As DateTime = DateTime.MinValue
            While (_testCount < 9) And _
                  (ts < New TimeSpan(50000000)) '// 5s
                ts = DateTime.Now - startTime
                System.Threading.Thread.Sleep(250)
                Console.WriteLine("TestForm: Waiting for events, count =
{0}, timeSpan = {1} s...", _
                         _testCount, ts.TotalSeconds)
            End While
        End Sub
    End Class

    ' // Proxy
    Public Class TestProcessEventsProxy
        Public Event TestEvent(ByVal Id As Long, ByVal msgId As Integer)

        Private _senders As List(Of System.Threading.Thread) = _
           New List(Of System.Threading.Thread)()
        Public Sub Test()
            For i As Integer = 1 To 3
                Dim newThread As System.Threading.Thread = _
                   New System.Threading.Thread(AddressOf myThread)
                newThread.Start()
                _senders.Add(newThread)
            Next i
        End Sub
        Protected Sub myThread()
            Dim obj As New TestProcess(AddressOf TestEventHook)
            obj.Test()
        End Sub

        Public Sub TestEventHook(ByVal objectId As Long, ByVal msgId As
Integer)
            Console.WriteLine("Proxy:    Message {0}.{1} is to be
retransmitted.", objectId, msgId)
            RaiseEvent TestEvent(objectId, msgId)
            Console.WriteLine("Proxy:    Message {0}.{1} has been
retransmitted.", objectId, msgId)
        End Sub
    End Class

    ' // worker process
    Public Class TestProcess
        Private Shared _id As Long = 0
        Private _myId As Long
        Private _myDelegate As TestEventDelegate

        Private _myMessageId As Long = 0
        Public Sub New(ByRef eventDeleGate As TestEventDelegate)
            _myId = Interlocked.Increment(_id)
            _myDelegate = eventDeleGate
        End Sub

        Public Sub Test()
            For i As Integer = 1 To 3
                _mymessageId += 1
                System.Threading.Thread.Sleep(300)
                Console.WriteLine("Process:  Message {0}.{1} is to be
sent.", _myId, _myMessageId)
                _myDelegate.Invoke(_myId, _myMessageId)
                Console.WriteLine("Process:  Message {0}.{1} has been
sent.", _myId, _myMessageId)
            Next i
        End Sub
    End Class

    '// test
    Sub Main()
        Dim obj As New TestForm()
        obj.Test()
    End Sub

End Module


My results:
===========

TestForm: Waiting for events, count = 0, timeSpan = 0 s...
Process:  Message 2.1 is to be sent.
Process:  Message 1.1 is to be sent.
Proxy:    Message 2.1 is to be retransmitted.
Proxy:    Message 1.1 is to be retransmitted.
TestForm: Message 1.2 arrived.
Proxy:    Message 2.1 has been retransmitted.
Process:  Message 2.1 has been sent.
Process:  Message 3.1 is to be sent.
Proxy:    Message 3.1 is to be retransmitted.
TestForm: Message 1.3 arrived.
Proxy:    Message 3.1 has been retransmitted.
Process:  Message 3.1 has been sent.
TestForm: Message 1.1 arrived.
Proxy:    Message 1.1 has been retransmitted.
Process:  Message 1.1 has been sent.
TestForm: Waiting for events, count = 3, timeSpan = 0,25 s...
Process:  Message 2.2 is to be sent.
Proxy:    Message 2.2 is to be retransmitted.
TestForm: Message 2.2 arrived.
Proxy:    Message 2.2 has been retransmitted.
Process:  Message 2.2 has been sent.
Process:  Message 3.2 is to be sent.
Proxy:    Message 3.2 is to be retransmitted.
TestForm: Message 2.3 arrived.
Proxy:    Message 3.2 has been retransmitted.
Process:  Message 1.2 is to be sent.
Proxy:    Message 1.2 is to be retransmitted.
TestForm: Message 2.1 arrived.
Proxy:    Message 1.2 has been retransmitted.
Process:  Message 1.2 has been sent.
Process:  Message 3.2 has been sent.
TestForm: Waiting for events, count = 6, timeSpan = 0,5 s...
Process:  Message 2.3 is to be sent.
Proxy:    Message 2.3 is to be retransmitted.
TestForm: Message 3.2 arrived.
Proxy:    Message 2.3 has been retransmitted.
Process:  Message 2.3 has been sent.
Process:  Message 1.3 is to be sent.
Proxy:    Message 1.3 is to be retransmitted.
TestForm: Message 3.1 arrived.
Proxy:    Message 1.3 has been retransmitted.
Process:  Message 1.3 has been sent.
Process:  Message 3.3 is to be sent.
Proxy:    Message 3.3 is to be retransmitted.
TestForm: Message 3.3 arrived.
Proxy:    Message 3.3 has been retransmitted.
Process:  Message 3.3 has been sent.
TestForm: Waiting for events, count = 9, timeSpan = 0,75 s...
Press any key to continue . . .
--
Shamil
 
-----Original Message-----
From: dba-vb-bounces at databaseadvisors.com
[mailto:dba-vb-bounces at databaseadvisors.com] On Behalf Of jwcolby
Sent: Friday, July 27, 2007 6:49 PM
To: dba-vb at databaseadvisors.com
Subject: [dba-VB] VB.Net - Proxy Class

I have a situation where I want to have a generic status form which updates
progress information for some very similar processes.  In all cases a
process class needs to raise events and the events need to be sunk in the
progress form.  Each event then updates one specific control on the progress
form.

Events:	
Current file	
FileComplete	
FilesToProcess
LinesComplete
Status

My problem is that AFAIK in order to sink events, an object has to be dimmed
WithEvents and the type of object has to be specified.  Thus the progress
form would have to be told in its header that it was working with a specific
class, and thus the progress form is no longer generic.  I know that I can
not use events and simply have the class open an instance of the progress
form directly, and directly manipulate the controls but I would prefer to
have a loosely coupled interface in the process class where it can just
raise events and if there is anyone who cares, it can process those events.

Can I use something like a proxy class where the proxy class knows about
process class and retransmits its events.  The progress form knows about the
proxy class.  Thus the progress form is loaded and passed in a proxy class.
That proxy class has been defined and hard coded to dim a specific object
which sources the events of interest?  

This seems like an inheritance thing for the proxy class.  Design a
ProgressProxy class which has code to source specific named events.  Create
a clsProcessProxy which inherits the ProgressProxy class.  In this class
hard code the object which is the original event source.  Name this object a
generic name so that the object itself can be changed, but the event sinks
never change and simply then call up to the parent (inherited ProgressProxy)
to retransmit the event.


clsProcess > clsProcessProxy inherits ProgressProxy > frmProgress (dims a
clsProcessProxy and is passed in an instance to set its local copy to)

Does any of this make sense?

John W. Colby
Colby Consulting
www.ColbyConsulting.com 

_______________________________________________
dba-VB mailing list
dba-VB at databaseadvisors.com
http://databaseadvisors.com/mailman/listinfo/dba-vb
http://www.databaseadvisors.com




More information about the dba-VB mailing list