我有一个WCF客户端代理,用于调用异步方法,如下所示:
var prox = new DoSomethingServiceClient("BasicHttpBinding_IDoSomethingService");
prox.DoSomethingCompleted += new EventHandler<AsyncCompletedEventArgs>(svcref_DoSomethingCompleted);
prox.DoSomethingAsync(0, Guid.NewGuid());
何时关闭/中止代理?
我是否使用发件人对象在svcref_DoSomethingCompleted
的第一行?
我在MS文档中看到它们在主线程中关闭代理,而不是在回调中。那是好习惯吗?对我来说似乎不对:
http://msdn.microsoft.com/en-us/library/ms730059(v=vs.110).aspx
我也发现了这一点,使用基于任务的异步,建议您在委托回调中关闭代理,这是我所期望的:
http://fun-with-blackhawk.blogspot.com/2010/03/wcf-exception-handling-in-asynchronous.html
答案 0 :(得分:1)
这就是WCF变得棘手的地方。当服务器调用回调方法时,它需要在客户端代理关闭之前完成该调用。这意味着对客户进行全程往返。 Microsoft示例请求客户端(通过Console.ReadLine())从用户输入以触发关闭。如果您想使用异步回调触发关闭,则需要获得创意。例如,您可以在新线程上对关闭进行排队,然后对执行进行延迟。这将允许回调完成其返回服务器的行程,然后关闭通道。
在回调中添加以下内容:
var currentChannel = OperationContext.Current.Channel;
ThreadPool.QueueUserWorkItem(o => CloseChannel(currentChannel));
然后关闭CloseChannel:
private static void CloseChannel<T>(T channel)
{
var clientChannel = (IClientChannel)channel;
var success = false;
try
{
//sleep before close so the main thread has a chance to catch up
Thread.Sleep(10000);
clientChannel.Close();
success = true;
}
catch (CommunicationException ce)
{
clientChannel.Abort();
}
catch (TimeoutException te)
{
clientChannel.Abort();
}
finally
{
if (!success)
clientChannel.Abort();
}
}