2011-07-28 3 views
0

Begin 및 End 메서드가 실행되지 않는 이유는 동기 인터페이스가 서비스 인터페이스에 정의되어 있습니까? 테스트 결과는 원래의 코드를 들어비동기 메서드 실행

public double GetSquareRoot(double value) 
{ 
    System.Diagnostics.Debugger.Log(0, "MyService", "Get - Start\n"); 
    Thread.Sleep(3000); 
    System.Diagnostics.Debugger.Log(0, "MyService", "Get - Finish\n"); 
    return Math.Sqrt(value); 
} 

public IAsyncResult BeginGetSquareRoot(double value, AsyncCallback callback, object  state) 
{ 
    System.Diagnostics.Debugger.Log(0, "MyService", "Begin - Start\n"); 
    GetSquareRootAsyncResult asyncResult = new GetSquareRootAsyncResult(callback,  state); 
    asyncResult.Value = value; 
    ThreadPool.QueueUserWorkItem(new WaitCallback((Callback)), asyncResult); 
    System.Diagnostics.Debugger.Log(0, "MyService", "Begin - Finish\n"); 
    return asyncResult; 
} 

public double EndGetSquareRoot(IAsyncResult asyncResult) 
{ 
    System.Diagnostics.Debugger.Log(0, "MyService", "End - Start\n"); 
    double result = 0; 
    using (GetSquareRootAsyncResult getSquareRootAsyncResult = asyncResult as  GetSquareRootAsyncResult) 
    { 
     getSquareRootAsyncResult.AsyncWaitHandle.WaitOne(); 
     result = getSquareRootAsyncResult.Result; 
    } 
    System.Diagnostics.Debugger.Log(0, "MyService", "End - Finish\n"); 
    return result; 
} 

: 나는 일부 디버그 정보를 추가 한 http://www.danrigsby.com/blog/index.php/2008/03/26/async-operations-in-wcf-iasyncresult-model-server-side/

:

  • 여기

    이 문서의 끝 부분에 예입니다 Get - Start
  • Get - Finish

그럼 난 IMyService에서 GetSquareRoot 방법을 삭제, 내가있어 :

  • 시작 -
  • 가져 오기를 시작합니다 - - 마침을
  • 콜백 - -
  • 가져 오기를 시작
  • 시작하기 시작 마침을
  • 콜백 - 완료
  • 끝 - 시작
  • 엔드 - 마침

왜 그럴까요?

클라이언트 번호 :

public partial class Form1 : Form 
{ 
    IMyService m_Client; 
    public Form1() 
    { 
     InitializeComponent(); 
     ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>("netTcp"); 
     factory.Open(); 
     m_Client = factory.CreateChannel(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     double value = 0; 
     Double.TryParse(m_ValueTextBox.Text, out value); 
     m_Client.BeginGetSquareRoot(value, OnEndGetSquareRoot, null); 
     m_StartButton.Enabled = false; 
     m_ResultTextBox.Text = @"Loading..."; 
    } 

    public void OnEndGetSquareRoot(IAsyncResult asyncResult) 
    { 
     this.Invoke(new MethodInvoker(delegate() 
      { 
       m_ResultTextBox.Text =        
        m_Client.EndGetSquareRoot(asyncResult).ToString(); 
       m_StartButton.Enabled = true; 
      })); 
    } 
} 

설명한 사례의 차이 IMyService 인터페이스 선언 GetSquareRoot의 부재이다.

+0

어떻게 웹 서비스 클라이언트 측을 호출합니까? –

+0

'using '블록이'IAsyncResult' 인수를 처리하지 않게할까요? – Amy

답변

0

다른 방법을 사용 중입니다. 동기 메서드는 비동기 메서드를 사용하여 구현되지 않습니다.

+0

두 경우 모두 클라이언트 코드가 동일합니다. 나는 그것을 질문에 추가 할 것이다. – TDV

3

이전에이 기사를 읽었으며 잘못되었습니다. 당신은 IMyService 계약 인터페이스의 서버 측 버전이므로 메소드의 동기식 정의가 없어야합니다. WCF 디스패처 런타임은 항상 메시지를 비동기 메시지 정의에 동기식 메서드 정의에 매핑하도록 선택합니다. 이것은 클라이언트가 비동기 적으로 서비스를 호출 할 수있게하려는 경우가 아니면 클라이언트와 원시 .NET 서비스 계약 인터페이스를 공유하지 않는 상황입니다.

또한 클라이언트가 메서드의 비동기 버전을 사용한다는 사실은 서버 측에 아무런 의미가 없음을 의미합니다. 클라이언트가 알고있는 모든 것을 위해 Linux의 다른 쪽에서 실행되는 Java 서비스 일 수 있습니다. 클라이언트는 항상 메소드의 동기화 또는 비동기 버전을 호출 할 수 있지만 항상 서비스 측면에서 동일하게 보입니다.

+0

감사합니다. 나는 두 가지 경우 모두 겉으로보기에 비동기적인 작업으로 보이기 때문에 그러한 행동에 혼란 스러웠다. 또한 http://msdn.microsoft.com/en-us/library/ms731177(v=vs.90)에서 유사한 예제를 발견했습니다.aspx – TDV

+0

네, MSDN 기사도 보았으며 결함도 있습니다. 동기식 메서드뿐만 아니라 비동기식 메서드도 정의 할 수있는 3.0 일 안에 시간이있을 수도 있지만, 생각해 보면 비합리적입니다. 비동기라면 계약 인터페이스에서 동기 메소드를 갖는 것이 무엇입니까? 앞서 말했듯이, 디스패처 런타임은 동기 버전이있는 경우 메소드의 비동기 버전을 절대 찾거나 사용할 수 없습니다. 그들이 말할 수있는 한 내가 기억할 수있는 한 "증거가 푸딩에있다"는 식으로 이런 식으로 일했습니다. –