AdvancedHMI Software
General Category => Support Questions => Topic started by: JanVanDerZijden on August 05, 2014, 03:56:10 AM
-
Hi guys,
I am getting a error when trying to subscribe. The m_Plc.Read functions is working perfectly, but is going too slow for my application.
this is my code:
private AdvancedHMIDrivers.EthernetIPforCLXCom m_Plc;
public MainPageViewModel()
{
m_Plc = new EthernetIPforCLXCom();
m_Plc.IPAddress = m_IPAddress;
m_Plc.ProcessorSlot = Convert.ToInt32(m_ProcessorSlot);
m_Plc.ComError += DoOnCommError;
m_Plc.SubscriptionError += DoOnCommError;
string testString = m_Plc.Read("MyTag");
int index = m_Plc.Subscribe("MyTag", 1, 2000, testPlcReaded);
}
private void testPlcReaded(object sender, MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs e)
{
try
{
Console.WriteLine(e.Values[0]);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
and this is the error I am getting:
m_SynchronizingObject.BeginInvoke(SubscriptionList(i).dlgCallBack, z)
wich is in the folder: EthernetIPforCLXCom.vb.
there is a null-pointer to m_SynchronizingObject.
Error-details: System.NullReferenceException was unhandled by user code
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=AdvancedHMIDrivers
StackTrace:
at AdvancedHMIDrivers.EthernetIPforCLXCom.DataLinkLayer_DataReceived(Object sender, PlcComEventArgs e) in C:\prj\TLLAB\TLLAB\AdvancedHMIBeta363 (1)\AdvancedHMIDrivers\EthernetIPforCLXCom.vb:line 1269
at MfgControl.AdvancedHMI.Drivers.CIP.OnDataReceived(PlcComEventArgs e)
at MfgControl.AdvancedHMI.Drivers.CIP.DataReceivedEIP(Object sender, PlcComEventArgs e)
-
To use subscriptions, you have to set the SynchronizingObject property. This is set automatically when you add a driver to the form in the designer. It's purpose it to return data back on the same thread the form runs on so the user code can put the data directly on visual controls without a cross thread error.
-
I cannot test this right now, but try to modify EthernetIPforCLX.vb start at about line 1268 to see if this resolves the issue:
Dim z() As Object = {Me, x}
'* 5-AUG-14 Added the ELSE to handle if the SynchronizingObject is not set
If m_SynchronizingObject IsNot Nothing Then
m_SynchronizingObject.BeginInvoke(SubscriptionList(i).dlgCallBack, z)
Else
If SubscriptionList(i).dlgCallBack IsNot Nothing Then
SubscriptionList(i).dlgCallBack.Invoke(Me, x)
End If
End If
-
Hé, this is some good code, I have replaced it and I do not have the error anymore. There is only problem left: The eventhandler is only triggered once. Besides it is triggered again when a new subscription is added.
Here is the code where I think it not going good:
If SubscriptionThread Is Nothing Then
SubscriptionThread = New System.ComponentModel.BackgroundWorker
AddHandler SubscriptionThread.DoWork, AddressOf SubscriptionUpdate
SubscriptionThread.RunWorkerAsync()
End If
SubscriptionThread is not nothing here, so the handler is not added.
Thanks in advance!
-
Update the method SubscriptionUpdate
Private Sub SubscriptionUpdate(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs)
While Not StopSubscriptions
If Not m_DisableSubscriptions And GroupedSubscriptionReads IsNot Nothing Then
'* 3-JUN-13 Do not read data until handles are created to avoid exceptions
If Not HandleCreated AndAlso m_SynchronizingObject IsNot Nothing Then
If m_SynchronizingObject IsNot Nothing AndAlso TypeOf (m_SynchronizingObject) Is System.Windows.Forms.Control _
Then
If Not DirectCast(m_SynchronizingObject, System.Windows.Forms.Control).IsHandleCreated Then
'Exit Sub
Else
HandleCreated = True
End If
End If
Else
Dim i As Integer = 0
While i < GroupedSubscriptionReads.Count And Not StopSubscriptions
SyncLock (ReadLock) ' Do not let the Internal request change during another read
Try
If Not m_DisableSubscriptions Then
InternalRequest = True
'Dim elapsed = timer.ElapsedMilliseconds
'23-OCT-11 Moved before the next 4 lines
Me.Read(GroupedSubscriptionReads(i).TagName, GroupedSubscriptionReads(i).NumberToRead)
'elapsed = timer.ElapsedMilliseconds
InternalRequest = False
Else
Threading.Thread.Yield()
End If
Catch ex As MfgControl.AdvancedHMI.Drivers.Common.PLCDriverException
Dim x As New MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs(ex.ErrorCode, ex.Message)
x.Values.Add(ex.Message)
Dim z() As Object = {Me, x}
Try
'**** TODO: Send error to proper control(i indexes the grouped subscriptions, not individual subscription)
If m_SynchronizingObject IsNot Nothing Then
m_SynchronizingObject.BeginInvoke(SubscriptionList(i).dlgCallBack, z)
Else
If SubscriptionList(i).dlgCallBack IsNot Nothing Then
SubscriptionList(i).dlgCallBack.Invoke(Me, x)
End If
End If
Catch ex2 As Exception
End Try
Catch ex As Exception
'* Send this message back to the requesting control
Dim x As New MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs(-99, ex.Message)
x.Values.Add(ex.Message)
Dim z() As Object = {Me, x}
'**** TODO: Send error to control
'm_SynchronizingObject.BeginInvoke(SubscriptionList(i).dlgCallBack, z)
'* Slow down the poll rate to avoid app freezing
SubscriptionList(i).SkipReads = 10
End Try
End SyncLock
i += 1
End While
End If
End If
Threading.Thread.Sleep(m_PollRateOverride)
End While
End Sub