/** * callback function that writes in_message out to the response stream * of client with ID in_key. */ public void Callback( string in_message, string in_key ) { CallbackContext context = Callbacks[ in_key ]; System.Diagnostics.Trace.WriteLine( "calling callback with message " + in_message ); /* * note that IsClientConnected doesn't get set until there has been a failure * so the first time we try to write to disconnected response will result in first chance exception * that we can't catch here for some reason */ if( context.Context.Response.IsClientConnected ) { context.Context.Response.Write( "<p>CallBack: Thread " + Thread.CurrentThread.ManagedThreadId + " " + in_message + "</p>" ); flush( context.Context ); } else { m_keysFlaggedForDeletion.Add( in_key ); } }
/* * BeginProcessRequest gets called automatically when the request comes in * We don't have to handle things in ProcessRequest/PageLoad and then set * everything up manually using RegisterAsyncTask like we do with an async * aspx page. We ignore */ public IAsyncResult BeginProcessRequest( HttpContext context, AsyncCallback callback, Object extraData ) { context.Response.Write( "<p>BeginProcessReqeust: Thread " + Thread.CurrentThread.ManagedThreadId + "</p>" ); // async is a dummy IAsyncResult to satisfy the method signature AsyncOperation async = new AsyncOperation( null, null, null ); // Callback context holds a callback and the httpcontext. // In hindsight we could have done this without the callback // so this is a possible point of refactoring. (TODO) CallbackContext callbackContext = new CallbackContext( new NotificationCallback( Callback ), context ); /** * TODO: this is too coarse of a lock, should be locking 'callbacks' */ lock( typeof( Register ) ) { Callbacks.Add( Guid.NewGuid().ToString(), callbackContext ); } return async; }