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