0

asp.netアプリケーションからのWCFサービス呼び出しに大きな疑問があります。デュプレックスチャネルとコールバック契約を実装しました。私は、同時モードが再入可能であり、インスタンスモード=セッションごとに使用しました。wcfサービスを呼び出すことができ、コールバックメソッドがトリガーされます。この時点まで、すべてが良好です。

しかし、サービスを最初に呼び出すときに、waithandlerオブジェクトを使用してそのサービスメソッドでその呼び出しを保持し、コールバックメソッドをトリガーするような方法を考えています。このコールバックはクライアント側のコードにヒットし、クライアント側から再び同じサービスクラスの別のメソッドを呼び出して、待機ハンドラーのロックを解除します。待機ハンドラーを使用して最初の呼び出しをロックし、コールバックメソッドをトリガーすると、クライアント側にコールバックされ、その後、同じサービス内の別のメソッドが再び呼び出されます。しかし、タイムアウト例外が発生しています...同じサービスで最初の呼び出しを保持して2番目の呼び出しを行うことは可能ですか?ASP.Netは初めてです

[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IMyServiceCallBacks))]
public interface IMyService
{
    [OperationContract]
    string GetData1();

    [OperationContract]
    void GetData2(bool isOK);
}


public interface IMyServiceCallBacks
{
    [OperationContract(IsOneWay = true)]
    void MyCallBack();
}

これはサービスクラスです

 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class MyService : IMyService
{                
    EventWaitHandle waitHandle;
    bool isook = false;

    public MyService()
    {

    }

    string IMyService.GetData1()
    {            

        waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);

        CallMethod();

        bool isOK = waitHandle.WaitOne();
        return "success";
    }

    private void CallMethod()
    {
        OperationContext.Current.GetCallbackChannel<IMyServiceCallBacks>().MyCallBack();
    }

    public void GetData2(bool isOK)
    {
        isook = true;
        waitHandle.Reset();
    }

 }

以下はクライアント側のコードです

 [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant,  UseSynchronizationContext = false, IncludeExceptionDetailInFaults = true)]
public class MyProxyClient : MyService, MyServiceCallback
{

   bool isOK;
   private MyServiceClient caServiceProxy
   private InstanceContext myInstanceContext;

   public MyService()
   {

     myInstanceContext = new InstanceContext(this);
     EndpointAddress endPointAddress = new EndpointAddress("http://localhost:2222222/MyWCF1/MyService.svc");

     caServiceProxy = new MyServiceClient(myInstanceContext, new WSDualHttpBinding(), endPointAddress);
   }

    public string GetData1()
    {
       string hhhh = caServiceProxy.GetData1();
       return hhhh;
    }

    public void GetData2(bool isOK)
    {
        caServiceProxy.GetData2(isOK);  // here it is processing but finally time out
    }

    // This is the call back
    public void MyCallBack()
    {
        isOK = true;
        GetData2(isOK);
    }   
 }

そして以下はウェブ設定serviceModeltagです

 <system.serviceModel>
<services>
  <service name="MyABService.MyService" behaviorConfiguration="WCFDuplex.Service1Behavior">
    <!-- Service Endpoints -->
    <endpoint address="" binding="wsDualHttpBinding" contract="MyABService.IMyService">         
      <identity>
        <dns value="localhost"/>
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="WCFDuplex.Service1Behavior">          
      <serviceMetadata httpGetEnabled="true"/>         
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

svcutilを使用してプロキシを生成しました。何か案が ???

ありがとう

4

1 に答える 1

0

1) これは、不安定なチャネルに依存してサービス メソッドの呼び出しを保留するのは悪い考えです。通話は長時間実行しないでください。したがって、定期的なポーリングに基づく HTTP デュプレックス。TCPの方が優れていますが、この種のシナリオでは、メソッド1にOneWay = trueで操作を使用することをお勧めします. サーバーはクライアントを登録し、状態を記憶/管理し、何らかの作業を行うことができます。また、クライアントはコールバックに従って動作を選択する必要があります。そのバックグラウンド スレッドの交換/同期には、AutoResetEvent/ManualResetEvent/TPL インフラストラクチャを使用できます。

2) OneWay = false のサービス メソッド内でコールバックを使用してクライアントに通知すると、エラーが発生する可能性があることを 90% 確信しています。例を参照してください。ここ

コールバック (Task.Factory.StartNew/QueueUserWorkItem など) を延期してメソッドを終了させることで問題を回避できると書きました。

于 2013-02-28T21:38:29.580 に答える