是这样,我在使用WCF,用的net.tcp绑定以及双工 
这是服务协定:[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IPlayerCallback))]
    public interface IPlayer
    {
        [OperationContract(IsInitiating = true)]
        string Login(string userName, string pwd);
    }
//协定实现
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Reentrant,UseSynchronizationContext=false)]
    public partial class Service : IPlayer
这是回调协定:[ServiceContract]
    interface IPlayerCallback
    {
        [OperationContract(IsOneWay = true)]
        void PlayerLogin(Player.PlayerContext player);
    }客户端调用服务的Login操作,在Login方法中会验证,然后决定是否可以登录,但是在返回之前会调用一次PlayerLogin回调,通过设置ConcurrencyMode.Reentrant可以防止死锁,但是客户端用的同步调用的Login,所以会无法处理服务回调的PlayerLogin,按理来说这时候PlayerLogin应该是进入排队,等待Login返回之后才会处理PlayerLogin,所以我将PlayerLogin设置了IsOneWay = true,使服务在调用PlayerLogin回调后能立刻返回,然后客户端也能继续处理接下去的代码,从而在接着处理排队中的PlayerLogin,而不会发生死锁。但是现在问题是调用服务的Login返回了,但是客户端仍然挂死在调用Login操作的那条语句上,然后回调函数PlayerLogin也没有触发,如果调用服务Login操作是在单独新开的一条线程上则没有以上的这个问题,请问这到底是怎么回事?

解决方案 »

  1.   

    http://blog.csdn.net/wuou/article/details/1892628
    应当是一样得。
      

  2.   

    我也碰到这个问题了。
    按我已有的知识来理解,服务端的并发模型设成Reentrant或Multiple应该能解决死锁问题,回调接口中的操作设成OneWay=True也应该能解决问题,结果两个都设了都无法解决这问题。
    求解。
      

  3.   

    看下你的回调函数是怎么写的,如果你的回调函数是在当前主线程上操作的,肯定将死锁,因为主线程正在执行Login操作,这个操作不执行完,将阻塞当前线程,回调函数不能执行,而回调函数不执行完,Login将不能返回,结果两个操作你等我,我等你,谁都不给对方执行完的机会,死锁因此产生了。
    建议你使用请求--应答这种简单的模式替代双工通讯,那样就不可能发送死锁的情况,双工必须要在异步编程中才能运行,由于操作比较复杂,且稍不留神就带来死锁情况,外加必须保持连接,还增加了维护连接状态的开销,因此我在初步尝试后就不在使用它了,得不偿失的技术。
      

  4.   

    回调 很麻烦,改成定时请求更可靠。
     如果系统负载高,不允许定时请求,楼主最好定一个tcp层上的协议。