[RESOLVED] Delegate Problem
Creating a simple program to monitor changes to Network Adapter(s) status, vis:
Code:
Imports System
Imports System.Net
Imports System.Net.NetworkInformation
Public Class Form1
Private Delegate Sub DoResults(ByVal nName As String, ByVal nStatus As String)
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
AddHandler NetworkChange.NetworkAddressChanged, AddressOf AddressChangedCallback
TextBox1.Text = "Monitoring for changes"
TextBox1.AppendText(vbNewLine)
End Sub
Private Sub UpdateText(ByVal AdapterName As String, ByVal AdapterStatus As String)
TextBox1.AppendText(AdapterName)
TextBox1.AppendText(" ")
TextBox1.AppendText(AdapterStatus)
TextBox1.AppendText(vbNewLine)
End Sub
Private Sub AddressChangedCallback(ByVal sender As Object, ByVal e As EventArgs)
Dim adapters As NetworkInterface() = NetworkInterface.GetAllNetworkInterfaces()
Dim n As NetworkInterface
For Each n In adapters
Dim adResult As New DoResults(AddressOf UpdateText)
Try
adResult.Invoke(n.Name.ToString, n.OperationalStatus.ToString)
Catch ex As Exception
MessageBox.Show("Exception: " & ex.Message)
End Try
Next n
End Sub
End Class
I'm getting an "Cross-thread operation not valid: Control Textbox1 accessed from a thread other than the thread it was created on" exception when I invoke the Delegate. Clearly there's a gap in my understanding; can someone perhaps explain what I ought to be doing ?
Re: [RESOLVED] Delegate Problem
No need to write custom delegates. Use the Action(Of T delegate or the MethodInvoker delegate. Side note Use Environment.NewLine over VbNewline. It's a is a string containing \r\n which are escape characters for return and new line vbNewLine is char 10 and char 13. The runtime decides which one to used based on the platform its being run on.
vb Code:
Imports System
Imports System.Net
Imports System.Net.NetworkInformation
Public Class Form1
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
AddHandler NetworkChange.NetworkAddressChanged, AddressOf AddressChangedCallback
Me.TextBox1.Text = "Monitoring for changes"
Me.TextBox1.AppendText(Environment.NewLine)
End Sub
Private Sub UpdateText(ByVal AdapterName As String, ByVal AdapterStatus As String)
Me.TextBox1.AppendText(String.Format("{0} {1}{2}",
AdapterName,
AdapterStatus,
Environment.NewLine))
End Sub
Private Sub AddressChangedCallback(ByVal sender As Object, ByVal e As EventArgs)
Dim adapters As NetworkInterface() = NetworkInterface.GetAllNetworkInterfaces()
Dim n As NetworkInterface
For Each n In adapters
Try
Me.Invoke(New MethodInvoker(Sub() UpdateText(Name.ToString, n.OperationalStatus.ToString)))
Catch ex As Exception
MessageBox.Show("Exception: " & ex.Message)
End Try
Next n
End Sub
End Class
Re: [RESOLVED] Delegate Problem
You could get rid of UpdateStatus altogether:-
vbnet Code:
'
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
AddHandler NetworkChange.NetworkAddressChanged, AddressOf AddressChangedCallback
TextBox1.Text = "Monitoring for changes"
TextBox1.AppendText(Environment.NewLine)
End Sub
Private Sub AddressChangedCallback(sender As Object, e As EventArgs)
Dim adapters As NetworkInterface() = NetworkInterface.GetAllNetworkInterfaces()
Dim n As NetworkInterface
For Each n In adapters
Try
TextBox1.Invoke(Sub()
TextBox1.AppendText(n.Name & " " & n.OperationalStatus.ToString & Environment.NewLine)
End Sub)
Catch ex As Exception
MessageBox.Show("Exception: " & ex.Message)
End Try
Next n
End Sub
You could even get rid of the AddressChangedCallback sub too if you wanted to get really terse.