jwcolby
jwcolby at colbyconsulting.com
Thu Jan 3 08:11:29 CST 2008
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