?
Solved

understanding delegates in vb.net

Posted on 2006-05-30
16
Medium Priority
?
472 Views
Last Modified: 2006-11-18
Hello experts, I am having a hard time understanding delegates.  I think I have an instance where a delegate would work for me, but I am having the hardest time understanding and creating a delegate.  I have downloaded numerous documents and looked at many web pages, but I cant seem to grasp the concept.  Can someone give a simple example or point me to a good tutorial?
0
Comment
Question by:tentavarious
  • 8
  • 6
  • 2
16 Comments
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 16790393
"I think I have an instance where a delegate would work for me..."

Can you give us the context of your problem?  Delegates are used in many ways...  =)
0
 

Author Comment

by:tentavarious
ID: 16790510
I think you where helping me before, it involved running a seperate thread within a class that querys a database and updates a label.  I thought I had it working, but I couldnt get the label to update.  I know I need a better understanding of delegates and how they work.  Basically the label text will show "Jobs Loading" and I add a period as the database is being queried.  I was using timers to accomplish this.  I just turn on the tjobs timer when the database query starts.
I thought using a delegate to update the lblloading label would work better.  Currently I am using two timers one timer runs every 5 minutes which querys the database and the other updates the label.
 
 Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
        'Timer2 event that updates the job list every 5 minutes if press is not running
        If jobstarted = False Then
            Timer2.Stop()
            buildjobs("Select Job_Number, Part_Number from Part_Info Where Part_Date >= '" & Today & "'", Me.lbcompleted)
            findjobs() 'procedure that updates the the job list
            Timer2.Start()
        End If
    End Sub
 

Private Sub tjobs_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tjobs.Tick
        If lblloading.Text.Length < 22 Then
            lblloading.Text += "."
        Else
            lblloading.Text = "Jobs Loading"
        End If
    End Sub
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 16790632
Delegates are basically function pointers.  They can be used with things like Windows API callbacks and event handler decriptions:

Examples and explanations:

Gate to Delegates in VB.NET
http://www.stardeveloper.com/articles/display.html?article=2003070801&page=1

Bob
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:tentavarious
ID: 16790687
ok, can someone give me step by step what is going on this bit of code i found.  I know what the end result is, I just dont understand all the steps needed to get there.

Public Class Bill
    Public Delegate Sub notifydelegate(ByVal msg As String)
    Private notify As notifydelegate

    Public Sub New(ByVal n As notifydelegate)
        notify = n
    End Sub
    Public Sub performaction()
        notify.Invoke("I did something here")
    End Sub
End Class


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim d As Bill.notifydelegate
        d = New Bill.notifydelegate(AddressOf performsomething)
        Dim biz(99) As Bill
        For i As Integer = 0 To 99
            biz(i) = New Bill(d)
        Next
        biz(23).performaction()
    End Sub
   
   
    Sub performsomething(ByVal msg As String)
        MessageBox.Show(msg)
    End Sub
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 16790888
When you define the delegate:

    d = New Bill.notifydelegate(AddressOf performsomething)

You are passing in a reference to a function (performsomething).  When the 'performaction' method is invoked, the function is located from the address pass to the constructor, and executed.  So, as a result the 'performsomething' method is the one executed.

The delegate is a go between that allows the call access to a different method.

Here is a good video from VB at the Movies:

Delegates
http://msdn.microsoft.com/vbasic/atthemovies/languageandfx/default.aspx


Bob
0
 

Author Comment

by:tentavarious
ID: 16791174
Ok, this will help me understand.  I modified the bill class to use a thread and add periods to a label.  I cant seem to get it to stop, and I dont think I am doing it correctly, i dont know how I should use the performsomething procedure

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim d As Bill.notifydelegate = New Bill.notifydelegate(AddressOf performsomething)
        Dim b As New Bill(d, lblloading)
        If Button1.Text = "Start" Then
            Button1.Text = "Stop"
            b.boolval = True
            b.performaction()
        Else
            b.boolval = False
            Button1.Text = "Start"
            b.performaction()
        End If

    End Sub
   
   
    Sub performsomething(ByVal msg As Label)
        MessageBox.Show(msg.Name)
    End Sub

Public Class Bill
    Dim blval As Boolean = False
    Dim s As System.Threading.Thread
    Public Delegate Sub notifydelegate(ByVal msg As Label)
    Private notify As notifydelegate
    Public lhold As Label
    Public Sub New(ByVal n As notifydelegate, ByVal nval As Label)
        notify = n
        lhold = nval
    End Sub
    Public Sub performaction()
        s = New System.Threading.Thread(AddressOf ilabel)
        notify.Invoke(lhold)
        s.Start()
    End Sub
    Public Property boolval() As Boolean
        Get
            Return blval
        End Get
        Set(ByVal Value As Boolean)
            blval = Value
        End Set
    End Property
    Sub ilabel()
        While boolval
            If lhold.Text.Length < 22 Then
                System.Threading.Thread.Sleep(1000)
                lhold.Text += "."
            Else
                lhold.Text = "Jobs Loading"
            End If
        End While
    End Sub
End Class
0
 

Author Comment

by:tentavarious
ID: 16791589
Ok, I made some changes and I cant get it to stop

Public Class Bill
    Dim blval As Boolean = False
    Dim s As System.Threading.Thread
    Public Delegate Sub notifydelegate(ByVal msg As Label)
    Private notify As notifydelegate
    Public lhold As Label
    Public Sub New(ByVal n As notifydelegate, ByVal nval As Label)
        notify = n
        lhold = nval
    End Sub
    Public Sub performaction()
        s = New System.Threading.Thread(AddressOf ilabel)
        s.Start()
    End Sub
    Public Property boolval() As Boolean
        Get
            Return blval
        End Get
        Set(ByVal Value As Boolean)
            blval = Value
        End Set
    End Property
    Sub startlabel()
        boolval = True
    End Sub
    Sub stoplabel()
        boolval = False
    End Sub
    Sub ilabel()
        While boolval
            System.Threading.Thread.Sleep(1000)
            notify.Invoke(lhold)
        End While
    End Sub
End Class


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim d As Bill.notifydelegate = New Bill.notifydelegate(AddressOf performsomething)
        Dim b = New Bill(d, lblloading)
        If Button1.Text = "Start" Then
            lblloading.Text = "Jobs Loading"
            Button1.Text = "Stop"
            b.startlabel()
            b.performaction()
        ElseIf Button1.Text = "Stop" Then
            b.stoplabel()
            Button1.Text = "Start"
        End If
    End Sub
    Sub performsomething(ByVal msg As Label)
        If msg.Text.Length < 22 Then
            msg.Text += "."
        Else
            msg.Text = "Jobs Loading"
        End If
    End Sub
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 16791826
.NET version?

Bob
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 16791847
The problem is the scope of 'b':

   Dim d As Bill.notifydelegate = New Bill.notifydelegate(AddressOf performsomething)
   Dim b = New Bill(d, lblloading)

If you declare these at module-level:

   Private d As New Bill.notifydelegate(AddressOf performsomething)
   Private b As Bill

then, change Button1_Click like this:

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    If Button1.Text = "Start" Then
      b = New Bill(d, lblLoading)
      lblLoading.Text = "Jobs Loading"
      Button1.Text = "Stop"
      b.startlabel()
      b.performaction()
    ElseIf Button1.Text = "Stop" Then
      b.stoplabel()
      Button1.Text = "Start"
    End If
  End Sub

Bob
0
 

Author Comment

by:tentavarious
ID: 16792116
My version is 1.1 and its still not stopping.  The label keeps incrementing
0
 

Author Comment

by:tentavarious
ID: 16792135
Ok, i got it working.  Just wondering if this would be good use of a delegate?
0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 1000 total points
ID: 16792337
1) Sometimes delegates just increase the level of complexity, and don't add much value

2) Can you do this another way?

3) I could do it this way, without delegates:

  Public Class Bill

    Private lhold As Label

    Private WithEvents m_timer As Timer

    Public Sub New(ByVal nval As Label)
      lhold = nval
    End Sub

    Public Sub Start()
      m_timer = New Timer
      m_timer.Enabled = True
      m_timer.Interval = 250
    End Sub

    Public Sub [Stop]()
      m_timer.Enabled = False

      lhold.Text = "Done"
    End Sub

    Private Sub m_timer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles m_timer.Tick
      If lhold.Text.Length < 22 Then
        lhold.Text += "."
      Else
        lhold.Text = "Jobs Loading"
      End If
    End Sub
  End Class

  Private b As Bill
  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    If Button1.Text = "Start" Then
      b = New Bill(Me.lblLoading)
      Button1.Text = "Stop"
      b.Start()
    ElseIf Button1.Text = "Stop" Then
      b.Stop()
      Button1.Text = "Start"
    End If
  End Sub

Bob
0
 

Author Comment

by:tentavarious
ID: 16792477
I tried doing it that way and I cant get the label to show up,  in my real program the button click event is replaced by a timer.  I have two procedures that i want to execute and have that label displayed while the procedures are executing.  The label doesnt show up.   I changed bill to Buildjobsclass and added the timer like you have above.  I then want to execute that class when timer2 fires every 5 minutes.


 Public b As Buildjobsclass

 Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
        'Timer2 event that updates the job list every 5 minutes if press is not running
        If jobstarted = False Then
            Timer2.Stop()
            b = New Buildjobsclass(lblloading)
            b.Start()
            buildjobs("Select Job_Number, Part_Number from Part_Info Where Part_Date >= '" & Today & "'", Me.lbcompleted) 'Querys sql database for matching part info
            findjobs() 'Queries oracle for job numbers
            Timer2.Start()
            b.Stop()
        End If
    End Sub
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 16792518
If you'll notice, though, that the Bill class above contains the timer itself.  Each instance would get its own timer, instead of shared one.

Bob
0
 

Author Comment

by:tentavarious
ID: 16792594
k got it working.  Figured out that my query was executing too fast.  I timed it and it was under 2 seconds.
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 16794170
Lol...   =)
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Well, all of us have seen the multiple EXCEL.EXE's in task manager that won't die even if you call the .close, .dispose methods. Try this method to kill any excels in memory. You can copy the kill function to create a check function and replace the …
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Screencast - Getting to Know the Pipeline

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question