[dba-VB] inheriting events

Shamil Salakhetdinov shamil at users.mns.ru
Thu Jan 3 09:05:39 CST 2008


Hi John,

1. Interfaces 

Interfaces allow having low coupled still compile time bound (i.e. for sure
syntactically correct) code...

I must say when I program something these days I do know there are many
principles used in this my programming but I often do not know how they are
called - have a look at this list:

http://rearchitect.wordpress.com/2006/02/12/software-design-principles-mined
-from-books-and-papers/ 

I'd bet you use many of these principles being an experienced developer but
if I ask you why you use them that would be not always easy to answer,
correct? :) (I mean when I do program something the first principle I use is
how good and streamlined the code I'm writing looks - if it doesn't and I
have time I do continue refactoring it until I see there is nothing to cut
out/refactor to make it even more simple and streamlined - and that always
works well - it's a simple principle :) but it isn't easy to explain that
simple principle(s) - they should be better shown as examples...

2) Yes, every winform has its own UI thread AFAIK

3) Context switching - I have to spend some time making sample solution for
that for Winforms - I do not program WinForms apps these days, only ASP.NET.
I can do that sample code tomorrow probably. If you're in hurry here is a
good source about what have to be done:

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

4) Application.DoEvents() - I'd never rely on it. The Sleep(...) I use is
just for sample purposes to simulate some work, not to let event to be
raised /processed. If you will use context switching then you'll always get
correctly updated winform and its controls...


--
Shamil
 

-----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:11 PM
To: dba-vb at databaseadvisors.com
Subject: Re: [dba-VB] inheriting events

Shamil,

Thanks for the example code.  I have a few questions.

1) What does the interface do, and what do interfaces in general do?  It
seems that they just force you to implement all of the pieces of something?
As such they are a programming tool to enforce consistency and reduce errors
due to inadvertently leaving something out?  Is that the purpose, or
something else, or something more?

2) Does each form have its own UI thread, or do all forms share a thread?

3) How do you implement context switching?  I definitely want to use a
worker thread for each import / export task, and I want to be able to have a
dedicated status form for each task.

4) I use a Application.DoEvents() at the end of each event handler to give
the system time to refresh the form so that it will display properly.  No
idea whether that is really required or not. Is your Sleep(500) just
something similar, or is it just to slow things down so that the numbers
count slowly? 

Hmm.. as I stare at the code in bewilderment it slowly sinks in.  You are
using an implements instead of inheritance so that 

a) The events can be raised directly in the class that wants to raise them
instead of having to call a method up in the parent class to raise the
method.  Much cleaner and easier.
b) The DirectCast has something to cast the object to which states that
events will be happening.


You do understand that I am barely able to understand what it all does, and
in fact probably still do not understand it all.  

Your code is a nice example of how to do this stuff, thanks for taking the
time to put this together.  

<sinks to his knees, hands clasped, pleading "code comments please oh
master">

;-)

John W. Colby
Colby Consulting
www.ColbyConsulting.com 
-----Original Message-----
From: dba-vb-bounces at databaseadvisors.com
[mailto:dba-vb-bounces at databaseadvisors.com] On Behalf Of Shamil
Salakhetdinov
Sent: Thursday, January 03, 2008 6:43 AM
To: dba-vb at databaseadvisors.com
Subject: Re: [dba-VB] inheriting events

Hi John,

Have a look below is the code you can use and generalize even more still
keeping it very simple. 

In fact there are two samples in this code: synchronous and asynchronous -
both work well in console mode as you can find. But the second async one has
to be changed to be used with WinForms because WinForms have their own UI
thread, and to call that thread properly from worker threads thread context
switching has to be implemented....


HTH,
Shamil

P.S. Code:

Option Explicit On

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 FileImporter
    Implements IProxyProgress
    Implements IFileProcessor

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

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

    Private Sub Execute(ByVal sleepInterval As Object) _
                Implements IFileProcessor.Execute
        For i As Integer = 1 To 5
            RaiseEvent EventOne("Event one from FileImporter")
            System.Threading.Thread.Sleep(500)
            RaiseEvent EventTwo("Event two from FileImporter", i)
            System.Threading.Thread.Sleep(500)
        Next i
    End Sub

End Class

Public Class FileExporter
    Implements IProxyProgress
    Implements IFileProcessor

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

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

    Private Sub Execute(ByVal sleepInterval As Object) Implements
IFileProcessor.Execute
        Dim interval As Integer = CType(sleepInterval, Integer)
        For i As Integer = 1 To 5
            RaiseEvent EventOne("Event one from FileExporter")
            System.Threading.Thread.Sleep(interval)
            RaiseEvent EventTwo("Event two from FileExporter", i)
            System.Threading.Thread.Sleep(interval)
        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 Main()  ' 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()
        proxyProgress = DirectCast(fileProcessor, IProxyProgress)
        AddHandler (proxyProgress.EventOne), AddressOf EventOneHandler
        AddHandler (proxyProgress.EventTwo), AddressOf EventTwoHandler
        list.Add(fileProcessor)
        ' two
        fileProcessor = New FileExporter()
        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()
        Dim workers(2) As System.Threading.Thread

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

        ' one
        fileProcessor = New FileImporter()
        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()
        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

--
Shamil

_______________________________________________
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