积极答复者
回调死锁,帮忙看一下

问题
-
Contracts
[ServiceContract(CallbackContract = typeof(IServerCallback))] public interface IServer { [OperationContract] void AddClient(); } public interface IServerCallback { string Password { [OperationContract] get; } }
实现[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class Server : IServer { public void AddClient() { var client = OperationContext.Current.GetCallbackChannel<IServerCallback>(); Console.WriteLine(client.Password); } } class Player : IServerCallback { public string Password { get; set; } }
Clientstatic void Main(string[] args) { Console.WriteLine("按回车启动客户端"); Console.ReadLine(); Player player = new Player(); player.Password = "12423"; ServerProxy server = new ServerProxy(player, new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:17017/server")); server.AddClient(); Console.WriteLine("操作完成"); Console.ReadLine(); }
结果在AddClient()时说此操作将死锁,因为在当前邮件完成处理以前无法收到答复。如果要允许无序的邮件处理,则在 ServiceBehaviorAttribute 上指定可重输入的或多个 ConcurrencyMode。
server必须是单线程。我在Player上加[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]没用。
问题代码下载http://www.box.com/s/ocne0zmxe8dxqq3dix01
请问应该怎么做?
答案
-
所以在回调契约里的操作都必须是单向操作,都必须有IsOneWay=true?
那对服务器实现所如下修改,
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
public class Server : IServer为什么又运行成功了呢?不是说回调操作都必须有IsOneWay=true?我可没有修改回调契约啊。
我重新查资料确认了一下,不需要OneWay=True.
这个
interface IMyContractCallback
{
[OperationContract]
void OnCallback();
}
[ServiceContract(CallbackContract = typeof(IMyContractCallback))]
interface IMyContract
{
[OperationContract]
void DoSomething();
}例子代码:WCF回调可能产生死锁情况,一般的解决办法有三种,
1.允许服务实例多线程,不过要自己实现代码来控制服务实例的访问。比较麻烦
2.
直接配置服务实例并发模式为重入:[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
class MyService : IMyContract
{
public void DoSomething()
{
IMyContractCa llback callback = OperationContext.Current.
GetCallbackChannel<IMyContractCallback>();
callback.OnCallback();
}
}3.就是设置回调操作
IsOneWay=true,这样回调以后立即释放服务实例,不需要等待客户端响应消息,也可以避免死锁。
Frank Xu Lei--谦卑若愚,好学若饥
【老徐的网站】:http://www.frankxulei.com/- 已标记为答案 爱让一切都对了 2012年2月9日 2:58
-
参考这个WCF回调死锁的解决办法,solution to deadlock of WCF callback
Frank Xu Lei--谦卑若愚,好学若饥
【老徐的网站】:http://www.frankxulei.com/- 已标记为答案 Frank Xu LeiModerator 2012年3月16日 7:10
全部回复
-
-
我想这个不是重点吧。我现在只是在练习WCF回调,我只是想让它运行成功。至于Server回调Client的什么方法(但必须是有返回值的),则不是重点。
你不喜欢回调Password,回调Name、string TellMeMore()等等都可以。
你这里定义WCF回调的时候参考的什么资料?
Frank Xu Lei--谦卑若愚,好学若饥
【老徐的网站】:http://www.frankxulei.com/微软WCF中文技术论坛
微软WCF英文技术论坛
Windows Azure中文技术论坛- 已编辑 Frank Xu LeiModerator 2012年2月6日 13:28
-
我想这个不是重点吧。我现在只是在练习WCF回调,我只是想让它运行成功。至于Server回调Client的什么方法(但必须是有返回值的),则不是重点。
你不喜欢回调Password,回调Name、string TellMeMore()等等都可以。
你这里定义WCF回调的时候参考的什么资料?
Frank Xu Lei--谦卑若愚,好学若饥
【老徐的网站】:http://www.frankxulei.com/微软WCF中文技术论坛
微软WCF英文技术论坛
Windows Azure中文技术论坛
参考我这个文章WCF分布式开发步步为赢(10):请求应答(Request-Reply)、单向操作(One-Way)、回调操作(Call Back).
Frank Xu Lei--谦卑若愚,好学若饥
【老徐的网站】:http://www.frankxulei.com/ -
-
所以在回调契约里的操作都必须是单向操作,都必须有IsOneWay=true?
那对服务器实现所如下修改,
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
public class Server : IServer为什么又运行成功了呢?不是说回调操作都必须有IsOneWay=true?我可没有修改回调契约啊。
我重新查资料确认了一下,不需要OneWay=True.
这个
interface IMyContractCallback
{
[OperationContract]
void OnCallback();
}
[ServiceContract(CallbackContract = typeof(IMyContractCallback))]
interface IMyContract
{
[OperationContract]
void DoSomething();
}例子代码:WCF回调可能产生死锁情况,一般的解决办法有三种,
1.允许服务实例多线程,不过要自己实现代码来控制服务实例的访问。比较麻烦
2.
直接配置服务实例并发模式为重入:[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
class MyService : IMyContract
{
public void DoSomething()
{
IMyContractCa llback callback = OperationContext.Current.
GetCallbackChannel<IMyContractCallback>();
callback.OnCallback();
}
}3.就是设置回调操作
IsOneWay=true,这样回调以后立即释放服务实例,不需要等待客户端响应消息,也可以避免死锁。
Frank Xu Lei--谦卑若愚,好学若饥
【老徐的网站】:http://www.frankxulei.com/- 已标记为答案 爱让一切都对了 2012年2月9日 2:58
-
参考这个WCF回调死锁的解决办法,solution to deadlock of WCF callback
Frank Xu Lei--谦卑若愚,好学若饥
【老徐的网站】:http://www.frankxulei.com/- 已标记为答案 Frank Xu LeiModerator 2012年3月16日 7:10