可靠的n层WCF(线程问题?)

时间:2010-02-02 15:46:55

标签: wcf multithreading n-tier-architecture

我正在使用层之间使用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);

第2层:是使用basicHttp进行Silverlight调用的WCF Web服务。这是第3层的代理。

[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 - &gt; httpBasic - &gt; IIS托管的代理WCF服务 - &gt; net.tcp - &gt; 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工具来为我生成代理类? (真的不想手动完成,合同中有一定程度的变化)

1 个答案:

答案 0 :(得分:0)

嗯,我想我已经解决了。这个主题帮助了我:

wcf service stops after few requests

基本上,我没有关闭我的第2层中的客户端代理,我发现这会导致阻塞。代码的演变是这样的,我最终删除了使用(){}块来促进异常不被客户端代理熄灭。但是,我进行了重组并重新测试,我的第2层代码现在看起来像:

    public SearchResult[] SearchForClients(string keywords, int? maxResults)
    {
        ClientBrokerClient clientBroker = CreateClientBrokerClient();

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

......例外并没有消失。