【问题标题】:Reliable n-Tier WCF (Threading issue?)可靠的 n 层 WCF(线程问题?)
【发布时间】:2011-01-12 05:20:52
【问题描述】:

我正在开发一个在层之间使用 WCF 的 n 层应用程序,这样:

第 1 层:Silverlight 应用程序 调用搜索请求

        IClientBroker clientBroker = UIContext.CreateWcfInterface<IClientBroker>("Data/ClientBroker.svc");
        clientBroker.BeginSearchForClients(SearchTerm, 20, (result) =>
        {
            SearchResult[] results = ((IClientBroker)result.AsyncState).EndSearchForClients(result).ToArray();

            // do stuff, update UI, etc.

        }, clientBroker);

Tier 2:是一个 WCF Web 服务,使用 basicHttp 供 Silverlight 调用。这是第三层的代理。

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
class ClientBroker : IClientBroker 
{
            [OperationContract] // as defined in IClientBroker
    public SearchResult[] SearchForClients(string keywords, int? maxResults)
    {
        ClientBrokerClient clientBroker = CreateClientBrokerClient();

        SearchResult[] searchResults=clientBroker.SearchForClients(keywords, maxResults);
        return searchResults;
    }
    }

第 3 层:是“服务器”,因为它提供了一个 net.tcp 端点(允许安全客户端在不使用 Silverlight 的情况下进行连接)。这是请求的最终目标。

    public class ClientBroker : IClientBroker // note this is different to tier 2 interface
    {

        public SearchResult[] SearchForClients(string keywords, int? maxResults)
        {
                    // do stuff
            if (maxResults.HasValue)
            {
                return results.Take(maxResults.Value).ToArray();
            }
            else
            {
                return results.ToArray();
            }
        }
     }

所以我的电话开始了:

Silverlight -> httpBasic -> IIS 托管的代理 WCF 服务 --> net.tcp --> EXE 托管的 WCF 服务

这很好用。我可以通过层传递标题,并维护会话等。而且它非常简洁。

但是通过它只需要几次调用就会导致通信超时。

服务器-EXE 完成其工作所花费的时间可以忽略不计。 我看到的问题是服务器“冻结”将结果返回到第 2 层。

我认为这与线程被锁定有关。

我环顾四周,发现理想的方法是让我的第 2 层异步运行,类似于下面的代码:

    public SearchResult[] SearchForClients(string keywords, int? maxResults)
    {
        ClientBrokerClient clientBroker = CreateClientBrokerClient();
        clientBroker.BeginSearchForClients(keywords, maxResults, result =>
            {
                SearchResult[] searchResults=((ClientBrokerClient)result.AsyncState).EndSearchForClients(result);
                // how to return results from here?
            }, clientBroker);

    }

但是当我的第 1 层客户端正在等待此方法的结果时,我该如何实现这一点,而该方法将在回调执行之前直接退出?我在构建 OperationContract 方法时遗漏了什么?

更新:

从那以后,我的服务器(第 3 层)通过从客户端发出许多请求来避开第 2 层的客户端。第 3 层的 net.tcp WCF 通道似乎坚如磐石。

更新 2:

这篇博文使用 IAsyncResult 模式进行了概述,我在这里没有提及。我在这里吠错树了吗? http://blogs.msdn.com/wenlong/archive/2009/02/09/scale-wcf-application-better-with-asynchronous-programming.aspx

更新 3:

好的,来自该博客的这段:

"如果你正在构建 N 层 WCF 服务,您将拥有 WCF 服务 调用 WCF 客户端代理的操作 用于其他后端服务。在这个 情况下,您需要确保 中间层(路由层)有 异步服务操作 调用异步 WCF 代理 操作。这样,您的 中间层不会用完线程 在处理许多缓慢的操作时。”

似乎证实了我的怀疑,即问题出在中间层(第 2 层)。我怎样才能实现这种开始/结束异步?我必须手动执行此操作还是可以保留 VS 工具为我生成代理类? (真的不想手动执行此操作,合同中有一定程度的变化)

【问题讨论】:

    标签: wcf multithreading n-tier-architecture


    【解决方案1】:

    好吧,我想我已经解决了。这个话题帮助了我:

    wcf service stops after few requests

    基本上,我没有关闭我的第 2 层中的客户端代理,我意识到这会导致阻塞。代码的演变使得我最终删除了 using() {} 块,以促进异常不会被客户端代理消除。但是,我已经重组和重新测试,我的第 2 层代码现在看起来像:

        public SearchResult[] SearchForClients(string keywords, int? maxResults)
        {
            ClientBrokerClient clientBroker = CreateClientBrokerClient();
    
            SearchResult[] searchResults=clientBroker.SearchForClients(keywords, maxResults);
            clientBroker.Close();
            return searchResults;
        }
    

    ...异常不会消失。

    【讨论】:

      猜你喜欢
      • 2011-07-27
      • 1970-01-01
      • 1970-01-01
      • 2012-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-13
      • 1970-01-01
      相关资源
      最近更新 更多