-->

To invoke a method asynchronously by using BeginIn

2019-06-03 18:35发布

问题:

I have this sample code that calls a method asynchronously using begininvoke, I'm executing this on a button click event on a webform.

After the button click, the user is redirected to a different page, where the user waits for the result.

The AuthorizePayment method takes a long time to run and returns a int code. I want to store that int value somewhere in session or a cookie(but not to dispaly) When I access Session to add that code, it throws null exception. How do I save this result in a session or a cookie?

Any idea?

    public class CreditCardAuthorizationManager
{
  // Delegate, defines signature of method(s) you want to execute asynchronously
  public delegate int AuthorizeDelegate(string creditcardNumber, 
                                        DateTime expiryDate, 
                                        double amount);

  // Method to initiate the asynchronous operation
  public void StartAuthorize()
  {
      AuthorizeDelegate ad = new AuthorizeDelegate(AuthorizePayment);
      IAsyncResult ar = ad.BeginInvoke(creditcardNumber, 
                                       expiryDate, 
                                       amount,                  
                                       new AsyncCallback(AuthorizationComplete), 
                                       null);
  }

  // Method to perform a time-consuming operation (this method executes 
  // asynchronously on a thread from the thread pool)
  private int AuthorizePayment(string creditcardNumber, 
                               DateTime expiryDate, 
                               double amount)
  {
    int authorizationCode = 0;

    // Open connection to Credit Card Authorization Service ...
    // Authorize Credit Card (assigning the result to authorizationCode) ...
    // Close connection to Credit Card Authorization Service ...
    return authorizationCode;
  }

  // Method to handle completion of the asynchronous operation
  public void AuthorizationComplete(IAsyncResult ar)
  {
    // See "Managing Asynchronous Completion with the EndInvoke Method"
    // later in this chapter.
  }
}

回答1:

You cannot reliably execute work across HTTP requests because the ASP.NET worker process might be aborted at an arbitrary moment. The payment might have been executed by the provider but your website might think it hasn't (and the payment is lost). I certainly wouldn't want to enter my credit card data into such a system.

A better way to do this is to run the payment on an AJAX request and make the authorization code execute synchronously.



回答2:

Instead of creating begin invoke and using delegates you can create a method with async keyword and returning the Task.

In your original method you can call the async method as

 Task<int> authorizationValue = await yourAsyncMethodCall(creditcardNumber, expirydate, amount)

  session["authorisation"] = authorizationValue;

Let me know if you need more specific example (my VS.net is broken so i had to type in here :()