【问题标题】:How to close Client Proxy with Async Call WCF如何使用异步调用 WCF 关闭客户端代理
【发布时间】:2014-03-02 13:13:28
【问题描述】:

我有一个 WCF 客户端代理,用于调用异步方法,如下所示:

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

何时关闭/中止代理?

我是否在 svcref_DoSomethingCompleted 的第一行中使用 sender 对象?

我在 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

【问题讨论】:

  • 我猜该示例有效,因为在 client.Close() 之前有一个阻塞 Console.ReadLine()。如果它不存在,它可能会在调用完成之前关闭客户端。

标签: c# wcf proxy


【解决方案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();
    }
}

【讨论】:

  • 您能否提供有关“它需要在客户端代理关闭之前完成该调用的更多详细信息。这意味着往返客户端的完整往返行程。”部分?
  • @xr280xr (免责声明:已经有几年了)回调中的通道中止可能执行得太快,并且您将在原始调用实际完成之前关闭通道,这会导致问题。 WCF 在幕后做了很多工作,并且在收到呼叫后确认呼叫实际上需要一些时间。在尝试中止之前稍作停顿可提供缓冲。这是一个blog post,里面有我当时写的代码。
猜你喜欢
  • 2012-10-03
  • 2013-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
  • 2016-06-16
相关资源
最近更新 更多