今天我有一个WCF问题,尽管它可能也适用于.NET中的其他网络模型。
我有一个公开发送(消息)OperationContract的WCF服务,它是OneWay = true。现在这个服务有一个回调通道,可以将消息返回给客户端。
无论如何,我正在尝试(成功)从我的客户端异步调用此Send方法。在DuplexSessionChannel上,我调用BeginSend(Message,OnSendComplete,null),我有一个OnSendComplete(IAsyncResult)方法,它在DuplexSessionChannel上调用EndSend(asyncResult)。
该服务具有CallbackContract并使用相同的BeginSend()/ EndSend()模式发送回客户端,该客户端在我通过OperationContext.Current.GetCallbackChannel获得的callBack通道上调用。
当从服务回调通道接收消息时,DuplexSessionChannel上的客户端调用BeginReceive()/ EndReceive()。
即使事情有效,我也不明白End <Operation>
()方法实际上做了什么,这就是我需要向我解释的内容。
我问,因为我在服务上的EndSend()调用(发送回客户端)时偶尔会出现异常,抱怨收集已被修改(我知道这个异常意味着什么,但不知道为什么会发生这种情况)或者究竟......)。我正在使用PollingDuplexHttpBinding和Silverlight客户端。
我不是WCF专家,但不要耽误细节,我需要知识。到目前为止,在我职业生涯的其他异步操作之前,我已经看到过这种开始/结束模式,但从未真正理解发生了什么。
提前致谢。
答案 0 :(得分:1)
听起来你的问题只是关于开始/结束APM(异步编程模型)。简而言之,APM采用类似
的同步方法R Foo(A a); // R is some result type, A is some argument type
并将其分解为异步的BeginFoo和EndFoo方法。主要优点发生在操作正在进行一些可能长时间运行的真正异步系统操作(例如,与网络通信)时(至少与其他功能相比;例如,与网络通信可能需要数百毫秒或更长时间)。此模式为您提供了一种告诉系统启动操作的方法,然后在操作结果准备就绪时回拨您。该模式的优点是您不必在此调用挂起时阻止托管线程(这意味着您可以拥有数千个待处理的网络读取/写入而无需数千个线程,欢呼,线程非常昂贵)。
因此,'BeginFoo'是你怎么说'用这些参数启动方法',然后当你被回调时(作为结果准备就绪的通知),'EndFoo'就是你得到结果的方式。在一般情况下,如果'Foo'可能抛出一个特殊的异常,那么这个异常可能来自'Begin'调用或'End'调用,你必须准备在两个地方处理它。
在类似Send()的情况下(可能会返回无效?我忘记了)这有点烦人/怪异因为它是单向的你只是想要“发射并忘记”。但是异常仍然可能发生(例如我试图发送但有人拔掉了我的网络电缆),因此这可能会产生异常......并且在给定开始/结束APM的情况下,这样的异常可能来自EndSend调用。实际上,异常是一种调用Send的“结果”,所以你调用EndSend提供了一种方法,让你在调用BeginSend之后向你抛出一个异常来说出错。