2013-04-16 2 views
0

Я смотрел MSDN и codeproject, но я все еще немного смущен.WCF Synchronous vs Asynchronous

Синхронное обслуживание по сравнению с асинхронным сервисом.

У меня есть конечная точка службы WCF. Эта служба имеет 2way SSL, применяемый к файлу web.config. Конечная точка клиента представляет собой набор Java WebLogic Suite на базе Oracle. У этого есть свой закрытый ключ и открытый ключ. Клиент должен общаться с нашим сервисом как асинхронно, так и синхронно.

Я могу только изменить положение вещей на Сервере СТОРОНЕ

http://www.codeproject.com/Articles/91528/How-to-Call-WCF-Services-Synchronously-and-Asynchr

http://msdn.microsoft.com/en-us/library/ms731177.aspx

Следующий код является синхронным часть файла SVC, CS: -

public getQuoteSyncResponse1 getQuoteSync(getQuoteSyncRequest request) 
    { 
     // Create new response 
     getQuoteSyncResponse1 res = new getQuoteSyncResponse1(); 

     res.GetQuoteSyncResponse = new GetQuoteSyncResponse(); 
     res.GetQuoteSyncResponse.Header = new GetQuoteResponseHeaderType(); 
     res.GetQuoteSyncResponse.Response = new GetQuoteSyncResponseType(); 

     // Create and populate header 
     res.GetQuoteSyncResponse.Header.MessageId = request.GetQuoteRequestSync.Header.MessageId; 
     res.GetQuoteSyncResponse.Header.Timestamp = request.GetQuoteRequestSync.Header.Timestamp; 
     res.GetQuoteSyncResponse.Header.QuoteId = request.GetQuoteRequestSync.Header.QuoteId; 
     res.GetQuoteSyncResponse.Header.CarrierId = request.GetQuoteRequestSync.Header.CarrierId; 


     List<RejectionType> rj = new List<RejectionType>(); 


     string _sTotalEmployees = request.GetQuoteRequestSync.Request.Employer.TotalEmployees; 
     int _TotalEmployees = 0; 
     if (int.TryParse(_sTotalEmployees, out _TotalEmployees) == false) 
     { 


      RejectionType rt; 
      rt = new RejectionType(); 
      rt.ReasonCode = "R01"; 
      rt.ReasonDescription = "Invalid Number of Employees"; 

      rj.Add(rt); 

      res.GetQuoteSyncResponse.Response.Rejections = rj.ToArray(); 

      res.GetQuoteSyncResponse.Response.ReceiptStatus = AcceptanceContentType.Reject; 

      return res; 
     } 

     res.GetQuoteSyncResponse.Response.ReceiptStatus = AcceptanceContentType.Success; 

     List<QuoteType> q = new List<QuoteType>(); 

     QuoteType qt; 

     qt = new QuoteType(); 
     qt.PlanId = "P345678"; 
     qt.EEPremium = 1220; 
     qt.EESPPremium = 2222; 
     qt.EEDepPremium = 3333; 
     qt.EEFamilyPremium = 4444; 
     qt.TotalMonthlyPremium = 3456; 
     qt.CoverageEffectiveDate = DateTime.Now; 

     q.Add(qt); 

     res.GetQuoteSyncResponse.Response.Quotes = q.ToArray(); 

     return res;} 

, так что эта синхронная часть службы работает. Теперь, как я могу использовать это, чтобы преобразовать его в асинхронный эквивалент?

Должен ли я запускать метод async в файле cs? или в файле svc? Я смущен ...

public getQuoteAsyncResponse getQuoteAsync(getQuoteAsyncRequest request, AsyncCallback callback, Object state) 
    { 
     // Create new response 
     getQuoteAsyncResponse res = new getQuoteAsyncResponse(); 

     return new getQuoteAsyncResponse(); 
    } 

я вроде понимаю, о обратном вызове гастронома-аллигаторе, состоянии объекта и таком, но может кто-то проиллюстрировать это дальше для меня? Как отформатировать асинхронную часть службы? В Сети так много примеров ... но все очень запутанно. У меня должно быть какое-то внутреннее непонимание этой концепции.

Редактировать: - Мне ответили, что серверная сторона не нуждается в манипулировании асинхронным способом связи. Тем не менее, я нашел это: -

Реализация асинхронной операции в WCF Подобно тому, как WCF сантехника позволяет клиентам вызывать операции сервера асинхронно, без сервера нужно знать ничего об этом, WCF также позволяет сервисные операции должны быть определены асинхронно , Так операция как:

[OperationContract] 
string DoWork(int value); 

... вместо этого может быть выражено в договоре услуг как:

[OperationContract(AsyncPattern = true)] 
IAsyncResult BeginDoWork(int value, AsyncCallback callback, object state); 

string EndDoWork(IAsyncResult result); 

Обратите внимание, что эти две формы эквивалентны, и неразличимы в метаданных WCF: они оба разоблачить операцию называемый DoWork [1]:

ответ

1

Асинхронная часть должна быть выполнена на клиенте. Это означает, что вы, вероятно, делаете что-то похожее на: var response = ServiceReference.GetSomething();

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

Вместо этого, вы можете

  1. По договору об оказании услуг, не забудьте украсить [OperationContract (IsOneWay = истина)]
  2. Если вы используете ServiceReference или serviceutil, он будет автоматически создавать "входящие события" и выполнить всю асинхронную работу на стороне клиента для вас.
  3. Если вы используете TCP, также создайте контракт обратного вызова, а затем на клиенте вы можете сделать что-то вроде ServiceReference1.IncomingSomething + = new eventHandler. Теперь вы можете сделать ServiceReferecnce1.GetSomething(), и ответ будет отправлен на функцию обработчика событий.
  4. Если это RESTful:

    public void MakeAsyncRequest(string url, string contentType) 
          { 
           try 
           { 
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
            request.ContentType = contentType; 
            request.Method = WebRequestMethods.Http.Get; 
            request.Timeout = 10000; 
            request.Proxy = null; 
    
            request.BeginGetResponse(new AsyncCallback(ReadCallback), request); 
           } 
           catch (Exception ex) 
           { 
            LogManager.LogException(ex); 
           } 
          } 
    
          private void ReadCallback(IAsyncResult asyncResult) 
          { 
           HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState; 
           string strContent = string.Empty; 
           string s; 
    
           try 
           { 
            using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult)) 
            { 
             Stream responseStream = response.GetResponseStream(); 
             using (StreamReader sr = new StreamReader(responseStream)) 
             { 
              //Need to return this response 
              strContent = sr.ReadToEnd(); 
             } 
            } 
           } 
           catch (Exception ex) 
           { 
            throw; 
           } 
          } 
    
+0

просто добавить несколько комментариев: - >> да, это RESTful сервис. >> Да, это TCP-ориентированная коммуникация. >> Я не могу ничего добавить на стороне клиента, клиентская сторона не обрабатывается мной. Единственное, что я могу координировать с клиентом, это 2way SSL-связь, RESTful Soap XML-пакеты и структура данных пакетов. Итак, код, который вы добавили, находится на стороне клиента или на стороне сервера? – Philo

+0

Вы понимаете код правильно, то есть это делается на стороне клиента. Вы ** не можете ** иметь асинхронную/синхронизацию в службе. Это должно быть сделано на стороне клиента. – Jeff

+0

Например, если клиент выполняет _var response = ServiceReference.GetSomething(); _ не имеет значения, что вы делаете на стороне службы, потому что клиент будет ждать ответа до перехода к следующей строке. Это зависит от шаблона проектирования ** ** для использования синхронизации служб или асинхронного использования. – Jeff