0

我对来自 asp.net 应用程序的 WCF 服务调用有很大的疑问。我实现了双工通道和回调合同。我使用的并发模式是可重入的,而实例模式=每个会话。我可以调用 wcf 服务,它会触发回调方法。到此为止,一切都很好。

但是我正在考虑一种方法,例如,当我第一次调用服务时,我使用 waithandler 对象将该调用保存在该服务方法中并触发回调方法。此回调命中客户端代码,并再次从客户端调用同一服务类中的另一个方法以释放该等待处理程序锁。当我使用等待处理程序锁定第一个调用并触发回调方法时,它正在回调客户端,之后,它再次调用同一服务中的另一个方法。但是我遇到了超时异常...可以在同一服务中保留第一个电话并拨打第二个电话?我对 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);
    }   
 }

下面是 web config 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) This is bad idea to rely on unstable channel and hold service method call. Calls shouldn't be long running. Therefore Http duplex based on periodical polling. TCP is better but for this kind of scenario I recommend to use operation with OneWay = true for Method1. Server can register clients, remember/manage states, do some work. And client must choose behavior according to callbacks. You can use AutoResetEvent/ManualResetEvent/TPL infrastructure for that background threads interchange/sync.

2) I'm 90% sure that notifying client with callback inside service method with OneWay = false can cause errors. See for ex. here

I wrote that you can avoid problems by deferring callback (Task.Factory.StartNew/QueueUserWorkItem etc.) to allow method to finish.

于 2013-02-28T21:38:29.580 回答