The Background Server Access classes handle the server access user requests in background threads to prevent the application from becoming unresponsive due to long server processing times or long timeouts in case of DCOM communication failures.
The Background Server Access classes are only available in the OPCDA.NET Professional Edition.
Class | Description |
BGCore |
This class provides an interface to the OPC Core Components server enumerator (OpcEnum.exe). |
BGServer | This class provides an interface to OpcServer class methods. The requests are queued and handled in a background thread. This class can only be used from classes that derive from System.Windows.Forms.Form. The completion notification with the browse result is synchronized with the user interface thread by internally calling Form.BeginInvoke(). Each server access is timeout checked. On timeout the GeneralError handler is called to inform the user application. The server access thread may continue to wait for the server call to finish or timeout. Further requests are not being handled before this happens. If the OPC server has become unresponsive then it's likely that it will not recover. The client application has to dispose all server access objects and try to connect to a new server instance. |
BGGroup | The BGGroup class handles the server access for data changed subscriptions and read/write operations. The server access is executed in a background thread. For data change callbacks to happen the BGGroup has to be in active state. Read an Write operations are independent of the active state of the group. This class does not have a public constructor. Instances are created by calling the BGServer.AddGroup method. This class can only be used from classes that derive from System.Windows.Forms.Form. The completion notification with the results is synchronized with the user interface thread by internally calling Form.BeginInvoke(). Each server access is timeout checked. On timeout the BGServer GeneralError handler is called to inform the user application. The server access thread may continue to wait for the server call to finish or timeout. Further requests are not being handled before this happens. |
Sample Application Code
C# |
VB |
private void Form1_Load(object sender, System.EventArgs e) { srv = new BGServer( this ); srv.GeneralError += new OnBGGeneralError(srv_GeneralError); srv.Connect( tbServerID.Text, null, null ); srv.GetStatus( null, new OnBGSrvGetStatus( OnGetStatus ) ); bTree = new BGBrowseTree( srv, tvServer ); bTree.BrowseModeOneLevel = ! this.cbBrowseAllInitially.Checked ; if( this.cbBrowseAllProperties.Checked ) bTree.PropertyIDsToGet = null ; bTree.Browse( new TreeNode( srv.Name ) ); srv.AddGroup( tbGroupName.Text, cbGroupActive.Checked, 100, 1, new DataChangeEventHandler(DataChangedHandler), null, new OnBGSrvAddGroup( OnAddGroup) ); } BGServer srv ; private void srv_GeneralError( string info, BGException ex, object tag) { if( (tag != null) && (tag.GetType() == typeof(string)) ) tbError.Text = info + " (" + tag.ToString() + ") : " + ex.Message ; else tbError.Text = info + " : " + ex.Message ; } private void OnGetStatus( BGException ex, SERVERSTATUS stat, object tag ) { if( ex != null ) tbInfo.Text = ex.Message ; else tbInfo.Text = stat.szVendorInfo ; } private void OnAddGroup( BGException ex, BGGroup grp, object tag ) { if( ex != null ) tbInfo.Text = ex.Message ; else { string[] ids = tbNodes.Lines ; OPCItemDef[] items = new OPCItemDef[ ids.Length ]; for( int i=0 ; i<ids.Length ; ++i ) { items[i] = new OPCItemDef( ids[i], true, i, typeof(void) ); } grp.AddItems( items, null, null ); } } private void DataChangedHandler( object sender, DataChangeEventArgs e ) { string txt = ""; foreach( OPCItemState ival in e.sts ) { txt += ival.DataValue.ToString() + "\r\n"; } tbItemValues.Text = txt ; } |
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load srv = New BGServer(Me) AddHandler srv.GeneralError, AddressOf srv_GeneralError srv.Connect(tbServerID.Text, Nothing, Nothing) srv.GetStatus(Nothing, New OnBGSrvGetStatus(AddressOf OnGetStatus)) bTree = New BGBrowseTree(srv, tvServer) bTree.BrowseModeOneLevel = Not Me.cbBrowseAll.Checked If Me.cbBrowseAllProp.Checked Then bTree.PropertyIDsToGet = Nothing End If bTree.Browse(New TreeNode(srv.Name)) srv.AddGroup(tbGroupName.Text, cbGroupActive.Checked, 100, 1, _ New DataChangeEventHandler(AddressOf DataChangedHandler), _ Nothing, New OnBGSrvAddGroup(AddressOf OnAddGroup)) End Sub Private srv As BGServer Private Sub srv_GeneralError(ByVal info As String, ByVal ex As BGException, ByVal tag As Object) If (Not tag Is Nothing) AndAlso (tag.GetType() Is GetType(String)) Then tbError.Text = info + " (" + tag.ToString() + ") : " + ex.Message Else tbError.Text = info + " : " + ex.Message End If End Sub Private Sub OnGetStatus(ByVal ex As BGException, ByVal stat As SERVERSTATUS, ByVal tag As Object) If Not ex Is Nothing Then tbInfo.Text = ex.Message Else tbInfo.Text = stat.szVendorInfo End If End Sub Private Sub OnAddGroup(ByVal ex As BGException, ByVal grp As BGGroup, ByVal tag As Object) If Not ex Is Nothing Then tbInfo.Text = ex.Message Else Dim ids As String() = tbNodes.Lines Dim items As OPCItemDef() = New OPCItemDef(ids.Length - 1) {} For i As Integer = 0 To ids.Length - 1 items(i) = New OPCItemDef(ids(i), True, i, Type.GetType("System.Void")) Next i grp.AddItems(items, Nothing, New OnBGGrpAddItems(AddressOf OnAddItems)) End If End Sub Private Sub DataChangedHandler(ByVal sender As Object, ByVal e As DataChangeEventArgs) Dim txt As String = "" For Each ival As OPCItemState In e.sts txt += ival.DataValue.ToString() + Constants.vbCrLf Next ival tbItemValues.Text = txt End Sub |