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
       |