是这样,我在使用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操作是在单独新开的一条线程上则没有以上的这个问题,请问这到底是怎么回事?
这是服务协定:[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操作是在单独新开的一条线程上则没有以上的这个问题,请问这到底是怎么回事?
解决方案 »
- system.data.oledb.oledbexception:ClassFactory无法供应请求的类别
- 求教:C# winform 选项卡tabPage中的文字如何显示下标
- C#开发串口通信
- console.writeline()与message.box()有什么区别?
- Crystalreport怎么在最后一页的页码后面加字
- 高手请进:如何计算二维“单元”数量
- html转word
- 我是个新手我有个问题,C#里面事件处理函数的sender,和e 这两个参数怎么用?
- C#在哪些地方不如C++强大呢?
- 请问如何在C#中调用非托管代码中的类?(C++生成)
- 数组怎样转换成List<T>?
- c#如何访问ftp
应当是一样得。
按我已有的知识来理解,服务端的并发模型设成Reentrant或Multiple应该能解决死锁问题,回调接口中的操作设成OneWay=True也应该能解决问题,结果两个都设了都无法解决这问题。
求解。
建议你使用请求--应答这种简单的模式替代双工通讯,那样就不可能发送死锁的情况,双工必须要在异步编程中才能运行,由于操作比较复杂,且稍不留神就带来死锁情况,外加必须保持连接,还增加了维护连接状态的开销,因此我在初步尝试后就不在使用它了,得不偿失的技术。
如果系统负载高,不允许定时请求,楼主最好定一个tcp层上的协议。