Огонь и Забудь из службы WCF - PullRequest
4 голосов
/ 28 февраля 2012

У меня есть несколько служб WCF REST в Azure. Внутри некоторых служб 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. Я не хочу, чтобы эти сервисы блокировались до тех пор, пока не будут возвращены SMS.

Я прочитал литературу, и три метода выделились

  1. Запустить и забыть, используя ThreadPool.QueueUserWorkItem - я видел некоторые ограничения на количество потоков, плюс если все мои вызовы wcf являются PerCall, будет ли QueueUserWorkItem безопасным?

  2. Иметь отдельную службу REST WCF с включенной опцией oneway для функции SendSMS, которая, в свою очередь, делает веб-запрос к внешним службам (хотя это выглядит как хак).

  3. Использовать BeginInvoke без EndInvoke

Наконец, есть что-то конкретное в Azure, которое мне не хватает. Любые указатели в правильном направлении будут оценены.

Ответы [ 3 ]

2 голосов
/ 28 февраля 2012

Взгляните на Односторонние контракты . Оберните ваш звонок во внешнюю службу с помощью службы, имеющей этот атрибут.

1 голос
/ 28 февраля 2012

Если у вас все в порядке с использованием стороннего элемента управления под названием 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

1 голос
/ 28 февраля 2012

Если вы называете их асинхронными вызовами, вы должны их уволить и забыть.Я думаю, что это будет самый простой способ.Вызов BeginInvoke.Любой из этих методов должен работать нормально, хотя.В Azure нет ничего конкретного, чтобы справиться с подобной ситуацией.

...