【发布时间】: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