简体   繁体   English

如何使用异步调用WCF关闭客户端代理

[英]How to close Client Proxy with Async Call WCF

I have a WCF client proxy that I use to call an async method like so: 我有一个WCF客户端代理,可用来调用如下异步方法:

var prox = new DoSomethingServiceClient("BasicHttpBinding_IDoSomethingService");
prox.DoSomethingCompleted += new EventHandler<AsyncCompletedEventArgs>(svcref_DoSomethingCompleted);
prox.DoSomethingAsync(0, Guid.NewGuid());

When do I close/abort the proxy? 我什么时候关闭/中止代理?

Do I do it in the first line in svcref_DoSomethingCompleted using the sender object? svcref_DoSomethingCompleted使用发件人对象在svcref_DoSomethingCompleted中的第一行中svcref_DoSomethingCompleted操作?

I see here in MS documentation that they close the proxy within the main thread, not in the callback. 我在MS文档中看到它们关闭了主线程中的代理,而不是回调中的代理。 Is that good practice? 那是好习惯吗? Seems wrong to me: 我觉得不对:

http://msdn.microsoft.com/en-us/library/ms730059(v=vs.110).aspx http://msdn.microsoft.com/en-us/library/ms730059(v=vs.110).aspx

I also found this, using task-based async which suggests that you close the proxy in the delegate callback, which is what I'd kind of expect: 我还发现了这一点,它使用基于任务的异步方式,建议您在委托回调中关闭代理,这是我所期望的:

http://fun-with-blackhawk.blogspot.com/2010/03/wcf-exception-handling-in-asynchronous.html http://fun-with-blackhawk.blogspot.com/2010/03/wcf-exception-handling-in-asynchronous.html

This is where WCF gets tricky. 这就是WCF变得棘手的地方。 When the server invokes a callback method, it needs to complete that call before the client proxy is closed. 当服务器调用回调方法时,它需要在关闭客户端代理之前完成该调用。 This means a full round trip to the client and back. 这意味着要往返于客户和客户之间。 The Microsoft example requests input from the user on the client side (via Console.ReadLine()) to trigger the close. Microsoft示例向客户端(通过Console.ReadLine())请求用户输入以触发关闭。 If you want to use an async callback to trigger a close, you'll need to get creative. 如果要使用异步回调触发关闭,则需要发挥创意。 For example, you could queue the close on a new thread, and then put a delay on the execution. 例如,您可以将关闭队列放在新线程上,然后延迟执行。 This would allow the callback to complete its trip back to the server and then subsequently close the channel. 这将允许回调完成返回服务器的行程,然后关闭通道。

Add something like this in your callback: 在回调中添加以下内容:

var currentChannel = OperationContext.Current.Channel;
ThreadPool.QueueUserWorkItem(o => CloseChannel(currentChannel));

and then this for CloseChannel: 然后针对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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM