This example places an asynchronous call to PlotValues and increases a counter while it waits for the call to be completed. The counter, shown in lblCount above, is dynamically updated while the call is in progress showing that the UI thread is no longer blocked waiting for the completion of the call. While waiting for the call, the sample adds to the listbox the result of the WaitForSingleObject call, which is typically 258 meaning timeout until the call completes. The WaitForSingleObject call is executed in a timer that fires every 10 milliseconds. WaitForSingleObject is coded to wait 10 milliseconds for the CallCompleteEvent so typically the 258 WAIT_TIMEOUT response will continue to be added to the listbox until the call completes at which time the listbox is cleared and the results of the call are displayed. On responsive systems you will likely need to change the start and end time to generate a long enough call to see the lblCount read something other than 0. In the example above you can see the Timer code executed 5 times before on the 6th time through the event was fired indicating the call had completed.
Building this sample requires two files, a form, and a module. The module is used to declare the Win32 WaitForSingleObject call.
Build the CallCompleteEvent example as follows:
1. Create a new project and add a reference to the PISDK library.
2. Add the visual elements as shown in the picture.
3. Cut and paste the code below into the project. Then continue with Step 4.
Option Explicit Dim Iasynch2 As IPIAsynchStatus2 Dim lHandle As Long Dim g_pvs As PIValues Dim g_count As Integer Private Sub Command1_Click() On Error GoTo eh List1.Clear If Len(Text1.Text) = 0 Or Len(Text2.Text) = 0 Then MsgBox "Please enter a server name and a tag name" Exit Sub End If If Len(Text3.Text) = 0 Or Len(Text4.Text) = 0 Then MsgBox "Please enter a start and end time" Exit Sub End If Dim srv As Server Set srv = Servers(Text1.Text) Dim cnxns As New Connections cnxns.Login srv Dim dt As PIData Set dt = srv.PIPoints(Text2.Text).Data Dim asynch As New PIAsynchStatus Set Iasynch2 = asynch lHandle = Iasynch2.CallCompleteEvent Timer1.Enabled = True ' place the call Set g_pvs = dt.PlotValues(Text3.Text, Text4.Text, 50, asynch) Exit Sub eh: MsgBox Err.Description End Sub Private Sub Form_Load() List1.Clear Text1.Text = Servers.DefaultServer.Name Text2.Text = "Sinusoid" Text3.Text = "*-1d" Text4.Text = "*" Timer1.Enabled = False Timer1.Interval = 10 g_count = 0 End Sub Private Sub Timer1_Timer() Dim lngWait As Long ' Note, normally the call will just return WAIT_TIMEOUT if the event ' isn't signaled within the specified 10 milliseconds lblCount.Caption = CStr(g_count) g_count = g_count + 1 lngWait = WaitForSingleObject(lHandle, 10) List1.AddItem CStr(lngWait) If lngWait = WAIT_OBJECT_0 Then ' Call is done, show the results Timer1.Enabled = False DoEvents ShowResults ElseIf lngWait = WAIT_ABANDONED Or lngWait = WAIT_FAILED Then MsgBox "Problem with call" End If End Sub Private Sub ShowResults() List1.Clear Dim pv As PIValue For Each pv In g_pvs List1.AddItem CStr(pv.TimeStamp.LocalDate) + CStr(pv.Value) Next g_count = 0 End Sub
4. Add a New Module to your project.
5. Cut and paste the following code into the module.
Public Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Public Const WAIT_OBJECT_0 = 0 Public Const WAIT_ABANDONED = &H80 Public Const WAIT_FAILED = &HFFFFFFFF