2009-09-13 2 views
0

다음과 같은 상황이 있습니다. 내 WCF 서비스를 사용하면 클라이언트가 일부 이벤트를 대기하도록 등록 할 수 있습니다. 대기는 서비스 측면에서 비동기식입니다. 즉, 웨이터가 등록되며 프로세스가 완료되면 웨이터에게 알림이 전송됩니다. 현재로서는 ManualResetEvent입니다.비동기 끝 <Method>이 WCF에서 호출되지 않았습니다.

이제이 메서드를 WCF를 통해 노출하고 싶습니다. AsyncPattern=true을 사용하여 IAsyncResultEndWait에 이벤트를 묶는 BeginWait이라는 두 가지 방법을 만들었습니다.이 중 하나는 AsyncWaitHandle.WaitOne()입니다. 그러나 클라이언트에서 BeginWait, EndWait으로 전화하면 서버 쪽 EndWait이 실행되지 않습니다. 나는 기본적으로 Channel.EndWait()을 호출하는 수동으로 구현 된 래퍼 (내 프록시 클래스는 ChannelBase<IWaitService>, IWaitService에서 파생 됨)를 사용하고 있으며이 함수는 실제로 호출됩니다. 서버 쪽에서는 전화가 도착하지 않습니다.

내가 뭘 잘못하고 있니? 후속 질문 : 비동기 호출이 작동하는 경우 클라이언트 측에서 동기식 호출을 수행하는 쉬운 방법이 있습니까?

+1

당신은 HTTP를 체크 아웃 할 수 있습니다 : 선은 과부하 WCF에 의해 전달 된 상태 개체가 작업에 끝나는

TaskFactory.StartNew(Action<object>, object) 

있도록

를 사용

var task = Task.Factory.StartNew((actionState) => IsPrime(a), state); 

으로 수정해야합니다 : //blogs.msdn.com/mjm/archive/2005/05/04/414793.aspx 주로 sync-as-async가 '로컬'일 (클라이언트에서 메소드 동기화 또는 비동기를 호출 할 수 있음을 서버에서 동기화 또는 비동기로 구현 될 수 있습니다.이 두 가지는 아무 관계가 없습니다. 서로). – Brian

+0

기본적으로 블로그 게시물에서 해결되었습니다. 귀하의 의견에 답을 할 수 있도록 받아 들일 수 있습니까? – Anteru

답변

0

동기식/비동기식 결정은 서버 또는 클라이언트 측에서 독립적으로 수행 할 수 있습니다. 클라이언트에서 EndWait을 호출해도 서버의 EndWait 호출로 변환되지 않습니다. 일을 단순하게 유지하고 혼동을 피하기 위해 동기화 클라이언트로 비동기 서비스를 테스트하는 것이 좋습니다.

EndWait 메서드 내에서 WaitOne을 호출하지 않는 것이 좋습니다. 이 메서드는 IAsyncResult가 프레임 워크에 완료 사실을 알린 후에 만 ​​호출됩니다. 이 세 가지 중 한 가지 방법으로 수행됩니다

  • CompletedSynchronously는 AsyncCallback는 AsyncWaitHandle는
  • 을 신호한다
  • 를 호출 사실
  • 을 반환
BeginWait를 완료하는 데 충분한 정보가 있다면

CompletedSynchronously는 true를 돌려 반환 전에 요청. 이것은 사실이 아닙니다. 다음과 같이 당신은 당신으로 ManualResetEvent와 다른 두 조건을 충족 할 수 있습니다

class EventBasedAsyncResult : IAsyncResult 
{ 
    private readonly ManualResetEvent _manualResetEvent; 
    private readonly AsyncCallback _asyncCallback; 
    private readonly object _asyncState; 

    public EventBasedAsyncResult(AsyncCallback callback, object asyncState) 
    { 
     _manualResetEvent = new ManualResetEvent(false); 
     _asyncState = asyncState; 
     _asyncCallback = callback; 
    } 

    public void WaitCompleted() 
    { 
     _manualResetEvent.Set(); 
     _asyncCallback(this); 
    } 

    public object AsyncState 
    { 
     get { return _asyncState; } 
    } 

    public WaitHandle AsyncWaitHandle 
    { 
     get { return _manualResetEvent; } 
    } 

    public bool CompletedSynchronously 
    { 
     get { return false; } 
    } 

    public bool IsCompleted 
    { 
     get { return _manualResetEvent.WaitOne(0); } 
    } 
} 

클라이언트가 동기 인 경우에도, 당신은 EndWait가 호출되는 것을 확인할 수 있습니다 이렇게하면 나는 생각한다.

2

라인

var task = Task.Factory.StartNew(() => IsPrime(a)); 

가 상태 객체임을 불평 ArgumentException이에 (작업) 결과 콜백

((IAsyncResult)task).AsyncState == null 

의 통화 결과 과부하

TaskFactory.StartNew(Action) 

를 사용 BeginXxx 메서드에 전달 된 상태 개체와 다릅니다.

((IAsyncResult)task).AsyncState.GetType().FullName == System.ServiceModel.Dispatcher.MessageRpc+Wrapper