【问题标题】:Fire and Forget from within a WCF service从 WCF 服务中触发并忘记
【发布时间】:2012-02-28 14:16:01
【问题描述】:

我在 Azure 上有一堆 WCF REST 服务。在一些 WCF 服务中,我调用 Http 请求(比如发送电子邮件/短信)到外部服务。 对非关键第三方服务的 http 请求。我不希望这会阻止我对客户呼叫的响应。需要一些关于在这种情况下使用的模式的指导。这是针对我的 wcf 服务中的“一劳永逸”模式。

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 请求(尽管这看起来像是一个 hack)。

  3. 使用 BeginInvoke 而不使用 EndInvoke

最后,我缺少什么 Azure 特定的东西。任何正确方向的指针将不胜感激。

【问题讨论】:

    标签: c# wcf c#-4.0 azure


    【解决方案1】:

    看看One Way Contracts。 使用具有此属性的服务来包装您对外部服务的调用。

    【讨论】:

      【解决方案2】:

      如果您将它们称为异步调用,您应该能够触发它们并忘记它们。我认为这将是最简单的方法。调用 BeginInvoke。不过,这些方法中的任何一种都应该可以正常工作。 Azure 没有专门的东西来处理这种情况。

      【讨论】:

        【解决方案3】:

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

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

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

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

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

        HttpClient 的命名空间是 Microsoft.Http

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-09
          • 1970-01-01
          • 1970-01-01
          • 2016-06-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多