2012-04-28 11 views
0

私はデュプレックスWCFサービスを持っています。サービス契約では、3つの非同期メソッドと1つの通常のメソッド(クローズセッション)があります。そのコールバック契約では、非同期ではない1つのvoidメソッドしかありません。WCF:コールバックコントラクト非同期、実装されていないためエラーbegin/endメソッド

私はsvcUtilでプロキシを生成するときに/ aパラメータを使用し、.csを取得します。このファイルを開くと、契約の非同期メソッドのBegin/endメソッドが生成されていることがわかります。なぜなら、このメソッドは契約で非同期としてマークされていないからです。とにかく、これは問題ではありません。

問題は、コールバック契約の方法にあります。私のクライアントアプリケーションでは、コールバックインターフェースを実装していますが、1つのメソッドsyncメソッドを実装しているので、Begin/Endメソッドはありません。しかし、コールバックインターフェイスを実装しているクラスがBegin/endメソッドを実装していないというエラーがあるため、コンパイルできません。

どのような問題がありますか?

ありがとうございました。 ダイムロク。

答えて

2

コールバックインターフェイスを実装するクラスは、非同期メソッドも実装する必要があります(インターフェイスで定義されているため)。ただし、インターフェイスに同じメソッドの同期バージョンと同期バージョンの両方がある場合はsynchronous one is invoked by defaultとなります。以下のコードでは、コールバッククラスの非同期操作だけをスローしますが、コードは正常に動作します。

public class StackOverflow_10362783 
{ 
    [ServiceContract(CallbackContract = typeof(ICallback))] 
    public interface ITest 
    { 
     [OperationContract] 
     string Hello(string text); 
    } 
    [ServiceContract] 
    public interface ICallback 
    { 
     [OperationContract(IsOneWay = true)] 
     void OnHello(string text); 

     [OperationContract(IsOneWay = true, AsyncPattern = true)] 
     IAsyncResult BeginOnHello(string text, AsyncCallback callback, object state); 
     void EndOnHello(IAsyncResult asyncResult); 
    } 
    public class Service : ITest 
    { 
     public string Hello(string text) 
     { 
      ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>(); 
      ThreadPool.QueueUserWorkItem(delegate 
      { 
       callback.OnHello(text); 
      }); 

      return text; 
     } 
    } 
    class MyCallback : ICallback 
    { 
     AutoResetEvent evt; 
     public MyCallback(AutoResetEvent evt) 
     { 
      this.evt = evt; 
     } 

     public void OnHello(string text) 
     { 
      Console.WriteLine("[callback] OnHello({0})", text); 
      evt.Set(); 
     } 

     public IAsyncResult BeginOnHello(string text, AsyncCallback callback, object state) 
     { 
      throw new NotImplementedException(); 
     } 

     public void EndOnHello(IAsyncResult asyncResult) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
    public static void Test() 
    { 
     string baseAddress = "net.tcp://" + Environment.MachineName + ":8000/Service"; 
     ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); 
     host.AddServiceEndpoint(typeof(ITest), new NetTcpBinding(SecurityMode.None), ""); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     AutoResetEvent evt = new AutoResetEvent(false); 
     MyCallback callback = new MyCallback(evt); 
     DuplexChannelFactory<ITest> factory = new DuplexChannelFactory<ITest>(
      new InstanceContext(callback), 
      new NetTcpBinding(SecurityMode.None), 
      new EndpointAddress(baseAddress)); 
     ITest proxy = factory.CreateChannel(); 

     Console.WriteLine(proxy.Hello("foo bar")); 
     evt.WaitOne(); 

     ((IClientChannel)proxy).Close(); 
     factory.Close(); 

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 
+0

スレッド「ThreadPool.QueueUserWorkItem(delegate {callback.OnHello(text);});」によってコールバックを呼び出す理由は何ですか?あなたは非同期の 'BeginOnHello'としてどのように呼び出すべきかアドバイスするのがとても親切でしょうか? 'EndOnHello'は命名規則によって呼び出されますか? – g18c

関連する問題