4

I have a bunch of WCF REST services on Azure. Inside some of the WCF services I invoke Http requests (say to send Email / sms) to external services. The http requests to the third party services that are non-critical. I do not want that to be blocking my response to the client call. Need some guidance on the pattern to be used in this case. This is for a fire and forget pattern within my wcf service.

Pseudo code for the WCF service

    [WebInvoke(UriTemplate = "process", Method = "POST")]
    [OperationContract]
    public bool DoSomeProcessing(DataEntity data)
    {
        bool result = ProcessData(data);
        //I do not want this call to block
        SendSMS();            
    }

    //Call to third party
    public void SendSMS()
    {
        HttpWebRequest objWebRequest = null;
        HttpWebResponse objWebResponse = null;

        objWebRequest = (HttpWebRequest)WebRequest.Create(url);
        objWebRequest.Method = "GET";

        //I do not want to wait for this response since often the web requests takes a bit of time. 
        //objWebResponse = (HttpWebResponse)objWebRequest.GetResponse();
    }

All my wcf services instance context mode are set to PerCall.

InstanceContextMode = InstanceContextMode.PerCall

There are some services that send Email and SMS. I do not want these services to block until the SMS calls return.

I read up on the literature and three methods stood out

  1. Fire and Forget using ThreadPool.QueueUserWorkItem - I am saw some limits on the number of threads plus if all my wcf calls are PerCall would QueueUserWorkItem be safe?

  2. Have a separate WCF REST service with the oneway option enabled for the SendSMS function that in turn make s the web request to the external services(although this seems like a hack).

  3. Use BeginInvoke without EndInvoke

Finally, is there anything Azure specific that I am missing. Any pointers in the right direction would be appreciated.

user529265
  • 820
  • 10
  • 27

3 Answers3

2

Have a look at One Way Contracts. Wrap your call to the external service with a service that exhibits this attribute.

Nick Ryan
  • 2,662
  • 1
  • 17
  • 24
1

If you call they as async calls, you should be able to fire them and forget. I would think that would be the easiest way. Calling BeginInvoke. Any of these methods should work fine though. Azure doesn't have anything specific to it to handle this type of situation.

Tom
  • 1,611
  • 10
  • 11
1

If you are fine with using a 3rd party control called RestSharp you would have the async method to perform a request as shown below:

            var client = new RestClient();
            client.BaseUrl = serviceBaseUrl;
            var request = new RestRequest(method) { DateFormat = DataFormat.Xml.ToString(), Resource = resourceUrl };
            request.AddParameter("text/xml", requestBody, ParameterType.RequestBody);      
            client.ExecuteAsync(request, callback);                

The callback method can be used if you need some notification later.

If you dont want to use a 3rd party dll then you can use the HttpClient object as shown below:

 var client = new HttpClient();
 client.DefaultHeaders.ContentType = "application/json";
 HttpRequestMessage req = new HttpRequestMessage("GET", "");
 client.SendAsync(req);

Namespace of HttpClient is Microsoft.Http

Rajesh
  • 7,766
  • 5
  • 22
  • 35