wcf - Silverlight 3 中 WCF 服务客户端代理的正确生命周期是什么?

标签 wcf silverlight wcf-client wcf-proxy

我在网上找到了对我的问题的混合答案。详细说明这个问题:

  • 我应该在每个异步调用中实例化一个服务客户端代理,还是每个 Silverlight 应用实例化一次?
  • 我是否应该显式关闭服务客户端代理(就像我在 ASP.NET MVC 应用程序中同步调用 WCF 服务那样)?

  • 我发现很多博主和论坛海报相互矛盾。任何人都可以指出任何明确的来源或证据来一劳永逸地回答这个问题吗?

    最佳答案

    自 V2(现在使用 V4)以来,我一直将 Silverlight 与 WCF 一起使用,这是我发现的。通常,打开一个客户端并仅使用该客户端进行所有通信非常有效。如果您不使用 DuplexHttBinding,它也可以执行相反的操作,每次打开一个新连接,然后在完成后关闭它。而且由于 Microsoft 在 Silverlight 中构建 WCF 客户端的方式,您不会看到保持一个客户端始终打开与为每个请求创建一个新客户端之间的性能差异。 (但是,如果您要为每个请求创建一个新客户端,请确保您也将其关闭。)

    现在,如果您正在使用 DuplexHttBinding,即,如果您想从服务器调用客户端上的方法,当然重要的是不要在每次请求时都关闭客户端。这只是常识。但是,没有任何文档告诉您,但我发现绝对关键的是,如果您正在使用 DuplexHttBinding,您应该一次只打开一个客户端实例。否则,您将遇到各种令人讨厌的超时问题,这些问题将非常非常难以解决。如果您只有一个连接,您的生活将变得更加轻松。

    我在自己的代码中强制执行此操作的方式是通过单个静态 DataConnectionManager 类运行我的所有连接,如果我在关闭第一个连接之前尝试打开第二个连接,该类将抛出一个 Assert。该类(class)的一些片段:

        private static int clientsOpen;
        public static int ClientsOpen
        {
            get
            {
                return clientsOpen;
            }
            set
            {
                clientsOpen = value;
                Debug.Assert(clientsOpen <= 1, "Bad things seem to happen when there's more than one open client.");
            }
        }
    
        public static RoomServiceClient GetRoomServiceClient()
        {
            ClientsCreated++;
            ClientsOpen++;
            Logger.LogDebugMessage("Clients created: {0}; Clients open: {1}", ClientsCreated, ClientsOpen);
            return new RoomServiceClient(GetDuplexHttpBinding(), GetDuplexHttpEndpoint());
        }
    
        public static void TryClientClose(RoomServiceClient client, bool waitForPendingCalls, Action<Exception> callback)
        {
            if (client != null && client.State != CommunicationState.Closed)
            {
                client.CloseCompleted += (sender, e) =>
                {
                    ClientsClosed++;
                    ClientsOpen--;
                    Logger.LogDebugMessage("Clients closed: {0}; Clients open: {1}", ClientsClosed, ClientsOpen);
                    if (e.Error != null)
                    {
                        Logger.LogDebugMessage(e.Error.Message);
                        client.Abort();
                    }
                    closingIntentionally = false;
                    if (callback != null)
                    {
                        callback(e.Error);
                    }
                };
                closingIntentionally = true;
                if (waitForPendingCalls)
                {
                    WaitForPendingCalls(() => client.CloseAsync());
                }
                else
                {
                    client.CloseAsync();
                }
            }
            else
            {
                if (callback != null)
                {
                    callback(null);
                }
            }
        }
    

    当然,烦人的部分是,如果您只有一个连接,则需要在该连接意外关闭时进行捕获并尝试重新打开它。然后你需要重新初始化你的不同类注册处理的所有回调。这并不是真的那么困难,但确保它做得正确很烦人。当然,该部分的自动化测试即使不是不可能,也是很困难的。 . .

    关于wcf - Silverlight 3 中 WCF 服务客户端代理的正确生命周期是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1711061/

    相关文章:

    .net - 如何检查 WCF 服务是否正常运行?

    silverlight - 如何在 Silverlight 应用程序中获取客户端大小?

    c# - 无法访问已处置的对象 - wcf 客户端

    c# - 如何将对象注入(inject) WCF 的 IErrorHandler?

    .net - 在 Silverlight 中使用自定义 WCF 序列化器

    传递 Null 参数的 WCF 调用

    c# - 委托(delegate).BeginInvoke

    c# - 交互触发 wp8.1(silverlight) 时的 xaml 解析错误

    WCF 服务,请求或增加 Binding 上的 SendTimeout 值

    wcf - 尝试使用 SVCUTIL.EXE 创建 Web 服务代理时出现 'No code was generated' 错误