Locked ASYNC/AWAIT Interactions with a Web Page

  • miércoles, 07 de diciembre de 2011 15:03
     
     

    Question/Suggestion: We need an example on how to use the AWAIT feature when interaction with a browser. Scenario: 1) A webpage collects user registration info and submits it to a WCF service. The service does 2 things: a) Saves the user information to a database b) Sends the user an email How do we return immediatley to the user after step (a); but AWAIT step (b)? Note: the user (browser) does not need a result from step (b)

     

    Let me illustatre using a slight modificaton of Eric Lippperts example in the Oct MSDN Marazine article (note I have changed the return type to string (instead of void) an taken out "await" on ObtainOrder. My question is can I insert return OK after ObtainOrder.  If so how can I get the ensuing code to run.

     

    async string ServeBreakfast(Diner diner)
    {
      var order = ObtainOrderAsync(diner);

    return "OK";
      var ingredients = await ObtainIngredientsAsync(order);
      var recipe = await ObtainRecipeAsync(order);
      var meal = await recipe.PrepareAsync(ingredients);
      diner.Give(meal);
    }

    • Editado SammyD jueves, 08 de diciembre de 2011 2:26
    •  

Todas las respuestas

  • miércoles, 07 de diciembre de 2011 18:38
    Moderador
     
     

    If this is done in the server, the second step doesn't need an await - you can just fire this off as an asynchronous task, since you don't care about when it completes.

     

    Your first step can use await/async, since the database saving operation can potentially be done asynchronously.  In that case, your WCF service could await the database save operation, then start a task for step b (but not await it), and return teh results of the DB save to the user immediately, returning.

     

     


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
  • miércoles, 07 de diciembre de 2011 18:42
     
     Respondida

    Async/Await does not change the Request/Reply nature of web communications. Async/Await only works within a single context.

    In your situation, there are several contexts, but they are all separate from each other. You can't interleave them with Async/Await.

    First, there is the context of the client browser. If this is Silverlight, then it has Async/Await capabilities. If this is JavaScript, then it can use Promises to get similar behavior. Either way, the web page in the client browser is one context.

    Next, there is the context of the WCF service. If the service is implemented asynchronously, then you can use Async/Await in the implementation. Each request to the WCF service is a separate context.

    There could also be a third context. There are only two if the client web page calls the WCF service directly. However, if the client web page uses a form, WebPage events, or a similar mechanism, then it will actually post back to the ASP.NET server. In this case, there is a third context: the web page on the web server.

     

    In your case, you want the WCF service to do two things, and send the Reply after the first one. Async/Await cannot help you do this, because it can't span multiple contexts. The WCF request is completed when the Reply is sent, so there's no more context in which to do step (b).

    Here's what you want to do:

    1) Write another service just for sending email. This can be a WCF service with a one-way binding. Strongly consider using a reliable messaging system such as MSMQ or Azure Queue Storage.

    2) Your registration WCF service will save the user information to the database, send a message to the email WCF service, and then return (completing its request).

           -Steve


    Programming blog: http://nitoprograms.blogspot.com/
      Including my TCP/IP .NET Sockets FAQ
      and How to Implement IDisposable and Finalizers: 3 Easy Rules
    Microsoft Certified Professional Developer

    How to get to Heaven according to the Bible