Delegates in .NET Framework are equivalent to Function pointers in C and C++ language. Delegates helps in multithreaded application where one thread is accessing a UI element created by another thread.
For e.g. the follwoing code will always return an error of type "Cross-thread operation not valid: Control 'TextBox1' accessed from a thread other than the thread it was created on."
Public Class Form1
Private trd As Thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
trd.Start()
Private Sub DoTask()
Dim i As Integer
i = 1
While i <= 1000
System.Console.WriteLine("the value of i is:" + i.ToString())
i = i + 1
Thread.Sleep(1000)
TextBox1.Text = i.ToString()
End While
End Sub
In the above example the thread is invoking the textbox1 which is running under MainForm Thread. That's why we receive this error. This can be removed with the help of Delegates. The following code shows how to remove the above error and run the code:
Public Class Form1
Private trd As Thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
trd = New Thread(AddressOf DoTask)
trd.IsBackground = True
trd.Start()
End Sub
i = 1
While i <= 1000
System.Console.WriteLine("the value of i is:" + i.ToString())
i = i + 1
Thread.Sleep(1000)
SetControlPropertyValue(TextBox1, "Text", i)
End While
End Sub
Private Delegate Sub SetControlValueCallback(ByVal oControl As Control, ByVal propName As String, ByVal propValue As Object)
Dim d As New SetControlValueCallback(AddressOf SetControlPropertyValue)
oControl.Invoke(d, New Object() {oControl, propName, propValue})
Else
Dim t As Type = oControl.[GetType]()
Dim props As PropertyInfo() = t.GetProperties()
For Each p As PropertyInfo In props
If p.Name.ToUpper() = propName.ToUpper() Then
p.SetValue(oControl, propValue.ToString(), Nothing)
End If
Next
End If
End Sub
End Class
For e.g. the follwoing code will always return an error of type "Cross-thread operation not valid: Control 'TextBox1' accessed from a thread other than the thread it was created on."
Imports System.Threading
Imports System.ReflectionPublic Class Form1
Private trd As Thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
trd = New Thread(AddressOf DoTask)
trd.IsBackground = Truetrd.Start()
End Sub
Private Sub DoTask()
Dim i As Integer
i = 1
While i <= 1000
System.Console.WriteLine("the value of i is:" + i.ToString())
i = i + 1
Thread.Sleep(1000)
TextBox1.Text = i.ToString()
End While
End Sub
In the above example the thread is invoking the textbox1 which is running under MainForm Thread. That's why we receive this error. This can be removed with the help of Delegates. The following code shows how to remove the above error and run the code:
Imports System.Threading
Imports System.ReflectionPublic Class Form1
Private trd As Thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
trd = New Thread(AddressOf DoTask)
trd.IsBackground = True
trd.Start()
End Sub
Private Sub DoTask()
Dim i As Integeri = 1
While i <= 1000
System.Console.WriteLine("the value of i is:" + i.ToString())
i = i + 1
Thread.Sleep(1000)
SetControlPropertyValue(TextBox1, "Text", i)
End While
End Sub
Private Delegate Sub SetControlValueCallback(ByVal oControl As Control, ByVal propName As String, ByVal propValue As Object)
Private Sub SetControlPropertyValue(ByVal oControl As Control, ByVal propName As String, ByVal propValue As Object)
If oControl.InvokeRequired ThenDim d As New SetControlValueCallback(AddressOf SetControlPropertyValue)
oControl.Invoke(d, New Object() {oControl, propName, propValue})
Else
Dim t As Type = oControl.[GetType]()
Dim props As PropertyInfo() = t.GetProperties()
For Each p As PropertyInfo In props
If p.Name.ToUpper() = propName.ToUpper() Then
p.SetValue(oControl, propValue.ToString(), Nothing)
End If
Next
End If
End Sub
End Class
Comments