Common_TimerRedraw_VBNet\ThreadedUpdate.aspx.vb
' Copyright 2010 ESRI ' ' All rights reserved under the copyright laws of the United States ' and applicable international laws, treaties, and conventions. ' ' You may freely redistribute and use this sample code, with or ' without modification, provided you include the original copyright ' notice and use restrictions. ' ' See the use restrictions. ' Imports Microsoft.VisualBasic Imports System Partial Public Class ThreadedUpdate Inherits System.Web.UI.Page #Region "Member Variables" ' Name of the resource to add graphics to Private _graphicsResourceName As String = "GraphicsResource" ' Amount of time to wait for the operation to complete when executing is initiated, in milliseconds Private _initialWaitTime As Integer = 2000 ' Amount of time to add to the execution of retrieving new graphics, in milliseconds Private _simulatedOperationLength As Integer = 5000 ' Key for session variable indicating whether graphics drawing is complete Private drawCompleteSessionKey As String = "DrawComplete" ' Array containing the names of the 48 contiguous states. Used in creating feature graphics for a ' random subset of these states. Private _states() As String = { "Alabama","Arizona","Arkansas","California","Colorado","Connecticut", "Delaware","Florida","Georgia","Idaho","Illinois","Indiana","Iowa","Kansas","Kentucky","Louisiana", "Maine","Maryland","Massachusetts","Michigan","Minnesota","Mississippi","Missouri","Montana", "Nebraska","Nevada","New Hampshire","New Jersey","New Mexico","New York","North Carolina", "North Dakota","Ohio","Oklahoma","Oregon","Pennsylvania","Rhode Island","South Carolina","South Dakota", "Tennessee","Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming" } #End Region #Region "Event Handlers - Page_Load, RequestReceived" Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) ' Initialize the session variable that indicates whether the current operation has completed If (Not Me.IsAsync) AndAlso Me.Session(drawCompleteSessionKey) Is Nothing Then Me.Session(drawCompleteSessionKey) = False End If End Sub Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) ' Add a handler for the PostbackManager's RequestReceived event. This event fires whenever doAsyncRequest ' is called on on the client tier PostbackManager. For more information on the PostbackManager, see the ' Common_PostbackManager sample. AddHandler PostbackManager1.RequestReceived, AddressOf PostbackManager1_RequestReceived End Sub ' Fires when a request is received that was initiated by a call to PostbackManager.doAsyncRequest on the client Private Sub PostbackManager1_RequestReceived(ByVal sender As Object, ByVal args As PostbackManager_VBNet.AdfRequestEventArgs) ' Parse the request arguments Dim requestArgs As System.Collections.Specialized.NameValueCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(args.RequestArguments) ' Indicates whether the graphics resource needs to be refreshed Dim refreshGraphics As Boolean = False ' Check the event argument and draw or clear graphics accordingly Select Case requestArgs("EventArg") Case "DrawGraphics" ' Get the current time Dim startTime As System.DateTime = System.DateTime.Now ' Invoke the graphics drawing logic on a new thread Dim drawGraphicsCallback As New System.Threading.WaitCallback(AddressOf DrawGraphics) System.Threading.ThreadPool.QueueUserWorkItem(drawGraphicsCallback) ' Initialize a time span that will store the elapsed time since starting the operation Dim elapsedTime As System.TimeSpan = System.DateTime.Now.Subtract(startTime) ' Allow the draw graphics operation the amount of time to complete indicated by _initialWaitTime Do While elapsedTime.TotalMilliseconds < _initialWaitTime ' Check whether the draw graphics operation is done If CBool(Me.Session(drawCompleteSessionKey)) Then ' The operation is complete, so the graphics resource needs to be refreshed refreshGraphics = True Exit Do End If ' Wait half a second before continuing the loop System.Threading.Thread.Sleep(500) ' Update the elapsed time elapsedTime = System.DateTime.Now.Subtract(startTime) Loop Case "CheckGraphics" ' Check whether the draw graphics operation is complete and set the refreshGraphics flag accordingly If CBool(Me.Session(drawCompleteSessionKey)) Then refreshGraphics = True End If Case "ClearGraphics" ' Call method to clear graphics and set the flag to refresh graphics ClearGraphics() refreshGraphics = True End Select If refreshGraphics Then ' Apply the graphics updates to the map Map1.RefreshResource(_graphicsResourceName) PostbackManager1.CallbackResults.CopyFrom(Map1.CallbackResults) ' Reset the session variable. We do this in a lock to avoid thread contention. SyncLock Me.Session.SyncRoot Me.Session(drawCompleteSessionKey) = False End SyncLock ' Set the postback manager's custom results. These will be used on the client to determine ' whether to set an update graphics timeout and to update the status text. If requestArgs("EventArg").Contains("Clear") Then PostbackManager1.CustomResults = "cleared" Else PostbackManager1.CustomResults = "complete" End If Else PostbackManager1.CustomResults = "pending" End If End Sub #End Region #Region "Private Graphics Manipulation Methods - DrawGraphics, ClearGraphics" ' Draws a random subset of states as feature graphics on the map. The object parameter is included so the ' method can be used to create a WaitCallback. Private Sub DrawGraphics(ByVal o As Object) ' Get the graphics resource Dim graphicsMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality = TryCast(Map1.GetFunctionality(_graphicsResourceName), ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality) ' Suspend the thread for the specified simulation duration System.Threading.Thread.Sleep(_simulatedOperationLength) ' Get a query functionality for the USA_Data resource Dim targetResourceName As String = "USA" Dim commonMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality = Map1.GetFunctionality(targetResourceName) Dim queryFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality = CType(commonMapFunctionality.Resource.CreateFunctionality(GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), Nothing), ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality) ' Get the names and IDs of the layers in the resource that can be queried Dim layerIDs() As String Dim layerNames() As String queryFunctionality.GetQueryableLayers(Nothing, layerIDs, layerNames) ' Get the index of the states layer Dim targetLayerName As String = "States" Dim targetLayerID As String = Nothing For i As Integer = 0 To layerNames.Length - 1 If layerNames(i).ToLower() = targetLayerName.ToLower() Then targetLayerID = layerIDs(i) Exit For End If Next i ' Initialize a filter for querying states Dim adfQueryFilter As New ESRI.ArcGIS.ADF.Web.QueryFilter() adfQueryFilter.ReturnADFGeometries = True adfQueryFilter.MaxRecords = 50 ' Specify that only the STATE_NAME field be queried Dim targetFieldName As String = "STATE_NAME" Dim stringCollection As New ESRI.ArcGIS.ADF.StringCollection(targetFieldName, ","c) adfQueryFilter.SubFields = stringCollection Dim stringBuilder As New System.Text.StringBuilder() ' Generate the number of states to display graphics for Dim randomizer As New System.Random() Dim numberStates As Integer = randomizer.Next(4, 26) ' Get a state name from the list Dim stateName As String = _states(randomizer.Next(_states.Length)) ' Add the number of unique state names specified by numberStates For i As Integer = 0 To numberStates - 1 ' Get the list Dim stateList As String = stringBuilder.ToString() ' Keep picking random state names until one is picked that isn't already on the list Do While stateList.Contains(stateName) stateName = _states(randomizer.Next(_states.Length)) Loop ' Add the state to the list stringBuilder.AppendFormat("'{0}',", stateName) Next i ' Remove the trailing comma from the list Dim whereClause As String = stringBuilder.ToString() whereClause = whereClause.Substring(0, whereClause.Length - 1) ' Specify that the query filter get features that match the states in the list adfQueryFilter.WhereClause = String.Format("STATE_NAME IN ({0})", whereClause) ' Execute the query Dim resultsTable As System.Data.DataTable = queryFunctionality.Query(commonMapFunctionality.Name, targetLayerID, adfQueryFilter) ' Convert results to a graphics layer and add to the map Dim resultsGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = ESRI.ArcGIS.ADF.Web.UI.WebControls.Converter.ToGraphicsLayer(resultsTable) Dim layerName As String = "Feature Graphics" resultsGraphicsLayer.TableName = layerName ' Lock the map functionality while it is being modified to avoid thread contention SyncLock graphicsMapFunctionality If graphicsMapFunctionality.GraphicsDataSet.Tables.Contains(layerName) Then graphicsMapFunctionality.GraphicsDataSet.Tables.Remove(layerName) End If graphicsMapFunctionality.GraphicsDataSet.Tables.Add(resultsTable) End SyncLock ' Set the session flag indicating the operation is complete to true. Lock the session while doing ' this to avoid thread contention. SyncLock Me.Session.SyncRoot Me.Session(drawCompleteSessionKey) = True End SyncLock End Sub ' Removes element or feature graphics from the map Private Sub ClearGraphics() ' Get the graphics resource Dim graphicsMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality = TryCast(Map1.GetFunctionality(_graphicsResourceName), ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality) ' Remove the element or feature graphics layer from the resource If graphicsMapFunctionality.GraphicsDataSet.Tables.Contains("Feature Graphics") Then graphicsMapFunctionality.GraphicsDataSet.Tables.Remove("Feature Graphics") End If End Sub #End Region End Class