locked
Possibly merely a misunderstanding of asynchronous webrequests RRS feed

  • Question

  • User-674010974 posted

    First of all, I apologize is this post is inappropriate in placement or content, but asking for help in forums has never been my forte.

    My question is fairly simple, and, as I implied in the header, possibly just spawned from a misunderstanding of the asynchronous webrequest. 

    Here is the scenario; I have a VB.NET GUI that collects information from the user and then sends it to a back-end server through a PHP script.  The PHP script runs several calculations on the values, enters them into databases, and in general takes a rather long time.  I don't need the response from the PHP script immediately, so I ran the webrequest asynchronous.
        Admittedly, this is my first time trying asynchronous... well, anything, and I am mostly working with a general grasp of the material gained through the omniscient internet.  As such, I was under the impression that the asynchronous request would continue functioning in the background while the rest of my code ran unaffected in the foreground. 
        After examining the flow of the program using breakpoints, however, I was somewhat surprised and disappointed to discover that it was immediately jumping from the async request to the callback function without even trying to execute the following code.  Somewhat miffed, I supposed it was possible that the code finished while I was scanning through the breakpoints (still entirely possible) so I took out all breakpoints, then added one right after the async request and one inside the callback procedure.  After running it, lo and behold, the code went the the callback first.  I can only assume that this is normal behavior and that I have misunderstood the fundamental purpose/use.

        If I am merely misunderstanding the purpose of the Asynchronous request, I would be very grateful if you would explain what/how the async request is used.

    Ah and here's the relevant segments of code:

    1         Dim state As WebRequestState = New WebRequestState(req) 
    2  
    3 'state is a predefined object for a webrequeststate 
    4  
    5         Dim ar As IAsyncResult = req.BeginGetResponse(New AsyncCallback(AddressOf _ 
    6                                  RequestComplete), state) 
    7          
    8         Dim timeout As Integer = 1000 * 60 
    9  
    10         ThreadPool.RegisterWaitForSingleObject(ar.AsyncWaitHandle, New _ 
    11                    WaitOrTimerCallback(AddressOf TimeoutCallback), state, timeout, True
    12  
    13  
    14     Private Sub RequestComplete(ByVal result As IAsyncResult) 
    15         Dim request As WebRequest 
    16         request = DirectCast(result.AsyncState, WebRequestState).Request 
    17     End Sub 
    18  
    19  


    When executing with breakpoints, I placed one on line line 8 and line 15, it jumped to line 15 immediately.

     

    Thursday, July 17, 2008 5:23 PM

All replies

  • User955742345 posted

    Even if something is asynchronous, the IDE may jump you to a different thread if that thread has started running.  I assume you are on a different thread, and that is confusing you. 

    What should happen is that you begin getting the response, which is an async process in another thread.  Everything between that and EndGetResponse will be executed, and if the requested async response has not returned, the thread should wait for that second thread to return to the main one. 

    After that, processing should continue as normal.

     

    There is a thread window in Visual Studio where you can view the active thread for the project, jump between threads, freeze processing on a thread, etc.

    While debugging, there are additional options under the debug menu.  Debug-> Windows -> Threads (default is ctrl + alt + h).  This thread window will show the threads available.  put your breakpoint at lines 5, 8, and 15.  When the debugger hits line 5, step over it.  If the debugger jumps to line 15, look at the thread window.  The thread "Location" value should tell you which thread you are on... One should have the name of the method where the BeginGetResponse was called, and the other should have the name of the RequestComplete method. 

    If you really want to test how this works, put a freeze on the thread inside RequestComplete (right-click that thread in the thread window and choose 'Freeze'), right-click the other thread, and choose "Switch to Thread."  Now you can continue debugging the method that invoked the async process before the async process completely finishes its cycle.  You will have a timeout error or a something similar if you never unfreeze the second thread, though (right click that thread and choose "Thaw."

    Thursday, July 17, 2008 6:54 PM
  • User-674010974 posted

     Thank you very much for the suggestions.  I will go try those now.  I do have a few questions about your response however, usually I pick such things up fairly quickly, but unfortunately this one seems to be giving me a real headache for some reason.  One thing confused me about what you said;

    Everything between that and EndGetResponse will be executed, and if the requested async response has not returned, the thread should wait for that second thread to return to the main one. 

     

    Does this mean that unless a statement is inside the StartGetResponse and EndGetResponse, it will not execute until the second thread is complete, thus defeating the purpose of running them in separate threads?

     Anyway, thank you for all the help you have given so far, and the help in the future.

     
    Oh, one last thing, let us say, for instance that you wanted to only have one object for making a connection to the PHP (webbridge), but you had multiple ways of parsing different responses, would you have to put that all in one callback function, with some form of case statement? or is there a more streamline method of altering the callback location, perhaps with public subs and a variable callback variable?

     

    Edit note:  After trying your suggestion, I could not locate the thread that contained the asynchronous process, even when setting breakpoints only inside the callback and after the new thread start point.  This is possibly because the PHP is executing faster than expected by an order of magnitude, but this seems rather unlikely.
     

    Friday, July 18, 2008 10:09 AM
  • User955742345 posted

     Thank you very much for the suggestions.  I will go try those now.  I do have a few questions about your response however, usually I pick such things up fairly quickly, but unfortunately this one seems to be giving me a real headache for some reason.  One thing confused me about what you said;

    Everything between that and EndGetResponse will be executed, and if the requested async response has not returned, the thread should wait for that second thread to return to the main one. 

     

    Does this mean that unless a statement is inside the StartGetResponse and EndGetResponse, it will not execute until the second thread is complete, thus defeating the purpose of running them in separate threads?

    That's correct.  BeginGetResponse will start a new thread to do the work, meanwhile your app continues its thing down to EndGetResponse.  If the callback was not invoked by the time the app reaches EndGetResponse, then the app will wait until the callback returns (a time-out should make it return, as well).

    The speed of the executing code

     

     Edit note:  After trying your suggestion, I could not locate the thread that contained the asynchronous process, even when setting breakpoints only inside the callback and after the new thread start point.  This is possibly because the PHP is executing faster than expected by an order of magnitude, but this seems rather unlikely.
     

     Sorry, I may have not worded my reply correctly.  You will only be able to see threads relevant to the .Net app in the thread window.  You may or may not see the PHP execution thread, depending on the setup.  (If you start a process with the web app, you should be able to see that process thread, though I haven't tested that.)

    When the breakpoint inside your callback hits, that means that the async process you called is done, but everything inside that callback should still be on the same thread that was launched by BeginGetResponse, and thus is your second thread.  If you hit the breakpoint at line 5, you should see the name of that method in the thread window (the current thread is highlighted/bold)-- remember its ID or some other identifiable property on it.  When the debugger hits the breakpoint in your callback, it should be on a different thread than the one that was current on the breakpoint at line 5.

    Friday, July 18, 2008 6:02 PM
  • User-674010974 posted

    Alright, thank you very much, I believe I have finally sorted this out.  Thank you for your help. 

    Monday, July 21, 2008 10:44 AM