4

다른 여러 웹 서비스를 차례로 호출하는 WCF 서비스가 있습니다. 서비스는 우선 순위에 따라 정렬되지만 병렬로 호출됩니다. 각 서비스는 true 또는 false로 응답하고 모든 응답이 수신되면 가장 선호되는 양수가 클라이언트에 반환됩니다.WCF 서비스에서 값을 반환 한 후 처리를 계속하는 방법

그러나이 중 언제라도 가장 선호하는 서비스는 긍정적 인 것으로 응답 할 수 있습니다. 이 시점에서 다른 서비스를 계속 쿼리하는 것은 의미가 없으므로 실행을 취소하고 결과를 클라이언트에 반환하고 싶습니다.

// Use parallelOptions to store the cancellation token 
ParallelOptions po = new ParallelOptions(); 
po.CancellationToken = cts.Token; 
Parallel.ForEach<IntegrationObj>(externalServices, po, x => 
{ 
    try 
    { 
     // Send requests 
     SendExternalRequest(x); 
     po.CancellationToken.ThrowIfCancellationRequested(); 
    } 
    catch (OperationCanceledException e) 
    { 
     /// Don't throw an exception if the loop was cancelled 
    } 
    catch (Exception e) 
    { 
     LogError(e.Message); 
    } 
}); 
if (positiveResponses.Count > 0) { 
    // Get the most preferred positive response and send it back to the client 
    res = positiveResponses.Where(
     x => x.ID == PreferredServiceID) 
     .FirstOrDefault(); 
} 
return res; 

위의 코드 내 코드의 매우 단순화 된 버전이지만, 본질적으로는 현재 가장 선호하는 서비스입니다 있는지 확인하기 위해 각 응답을 확인 :

그렇게 많이 나는 할 수있다. 그렇다면 루프를 취소합니다. 이미 루프를 종료하기 전에 완료하기 위해 호출 된 모든 서비스를 기다립니다 이런 식으로 루프를 취소 그러나

.... 어떤 서비스도 시간 초과 될 수있는 합리적인 기회가 있습니다. 물론 이는 부정적인 것으로 취급됩니다. 시간 초과 중 하나가 발생하면 내 응답 시간에 10 초가 추가됩니다. 내가하고 싶은 무엇

는 다음 중 하나입니다 이미 시작했습니다 서비스에서 오는 응답 처리를 계속 한 후 클라이언트에

  1. 반환 선호하는 서비스와 (이 로깅 순전히 목적에 따라 서비스의 긍정적/부정적 비율을 알 수 있음).
  2. 루프를 즉시 취소하고 나머지 응답을 잊어 버리십시오. 이상 반응으로 긍정적 인 반응을 보인 서비스는 그처럼 기록되지 않아서 자신의 선호도 등급에 영향을 미칠 것이기 때문에 이것을 원하지 않습니다.

    내가 할 수 달성 할 무엇인가 :

그래서 내 질문이 무엇입니까? parallel.foreach가 작업에 가장 적합한 도구가 아니거나 클라이언트에 응답 한 후 응답을 기록하지 못할 수도 있음을 알고 있습니다. 가장 중요한 요구 사항은 클라이언트가 "승자"가 이미 선택되었을 때 서비스가 응답 할 때까지 기다리지 않고도 빠른 응답을 받는다는 것입니다.

답변

1

현재 설정되어있는 방법은 모든 서비스가 병렬로 시작되지만 모든 서비스가 완료된 후에 만 ​​수표가 프로그래밍되도록하는 것입니다.
foreach 접근 방식을 계속 사용하려면 if 조건을 foreach 내부에 작성할 수 있습니다. 서비스가 먼저 완료되면 긍정적 인 응답을 직접 실행하고 그에 따라 반응 할 수 있습니다 (값을 반환하거나 다른 것을 죽일 수 있음).).
이 접근법에는 더 많은 스레드 insafeties가 있습니다 (서비스 중 하나가 쓰려고하는 목록에서 읽음). 또한 2 개의 서비스가 동시에 종료되어 if 문이 두 번 실행될 수도 있습니다.
foreach 접근 방법의 대안은 각 서비스에 대한 스레드를 만들고 모든 스레드를 목록에 넣은 다음 모든 스레드가 시작한 후 바로 while 루프를 시작하여 완성 된 서비스. 이 방법을 사용하면 while 루프를 위반하여 다른 스레드가 계속 실행되는 동안 값을 반환 할 수 있습니다.

+1

나는 결국 두 번째 방법을 사용했다. 결과가 결정된 후에도 나머지 서비스는 계속 쿼리되지만 Parallel.ForEach보다 앞서 성능이 뛰어나다는 것을 의미합니다. – Maloric

관련 문제