从WCF服务中激发并忘记

本文关键字:忘记 WCF 服务 | 更新日期: 2023-09-27 18:26:06

我在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

有一些发送电子邮件和短信的服务。我不希望这些服务在短信呼叫返回之前被阻止。

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

  1. Fire and Forget using ThreadPool.QueueUserWorkItem-我看到线程数量有一些限制,如果我所有的wcf调用都是PerCall,QueueUserWorkItem会安全吗?

  2. 有一个单独的WCF REST服务,并为SendSMS功能启用单向选项,从而向外部服务发出web请求(尽管这看起来像是黑客攻击)。

  3. 使用BeginInvoke而不使用EndInvoke

最后,我还缺少什么Azure特有的东西吗。任何指向正确方向的指针都将受到赞赏。

从WCF服务中激发并忘记

看看单向合同。使用显示此属性的服务包装对外部服务的调用。

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

如果您可以使用名为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