在WCF服务中触发并忘记

时间:2012-02-28 14:16:02

标签: c# wcf c#-4.0 azure

我在Azure上有一堆WCF REST服务。在一些WCF服务中,我调用Http请求(比如发送Email / sms)到外部服务。 http请求非关键的第三方服务。我不希望这阻止我对客户端调用的响应。需要一些关于在这种情况下使用的模式的指导。这是我的wcf服务中的fire and forget模式。

WCF服务的伪代码

    [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();
    }

我所有的wcf服务实例上下文模式都设置为PerCall。

InstanceContextMode = InstanceContextMode.PerCall

有些服务会发送电子邮件和短信。在SMS调用返回之前,我不希望阻止这些服务。

我阅读了文献,其中有三种方法脱颖而出

  1. 使用ThreadPool.QueueUserWorkItem触发并忘记 - 我看到线程数有限制加上如果我的所有wcf调用都是PerCall会使QueueUserWorkItem安全吗?

  2. 有一个单独的WCF REST服务,其中为SendSMS功能启用了单向选项,而该功能反过来又成为对外部服务的Web请求(尽管这看起来像是一个黑客攻击)。

  3. 使用不带EndInvoke的BeginInvoke

  4. 最后,是否有任何我特定的Azure缺失。任何指向正确的方向将不胜感激。

3 个答案:

答案 0 :(得分:2)

看看One Way Contracts。 使用具有此属性的服务将您的呼叫包裹到外部服务。

答案 1 :(得分:1)

如果你把它们称为异步通话,你应该可以解雇它们并忘记。我认为这将是最简单的方法。调用BeginInvoke。任何这些方法都应该可以正常工作。 Azure没有任何特定的东西来处理这种情况。

答案 2 :(得分:1)

如果您使用名为RestSharp的第三方控件,则可以使用异步方法执行请求,如下所示:

            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);                

如果稍后需要通知,可以使用回调方法。

如果您不想使用第三方dll,则可以使用HttpClient对象,如下所示:

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

HttpClient的命名空间是Microsoft.Http