简单的客户端 WCF 缓存






3.62/5 (6投票s)
为 WCF 实现客户端缓存
引言
在使用 Windows Communication Framework (WCF) 或 Remoting 时,开发人员面临的一个问题是由于频繁的接口调用导致的性能下降。为了解决这个问题,我开发了一种将通常是静态数据存储在客户端的方法,以减少对服务器端这些数据的调用。该方法的关键在于,您的对象和 WCF 调用不需要了解这种缓存,一切都在 WCF 客户端代码中完成,在向服务器发起调用之前。
我将通过一个简单的 WCF 应用程序来演示这种方法,该应用程序从 Northwind
的 Categories
表中提取数据,并将这些类别缓存在客户端。当发起通过 ID 检索类别时,它不必向服务器发起调用,可以直接从客户端缓存中提取数据。
注意:我在努力提高 WinForms(智能客户端)应用程序的性能时,想出了这个解决方案,该应用程序遇到了性能问题。我发现性能问题的根本原因是对数据库的调用过多。最初的实现是使用 Remoting 而不是 WCF 完成的。
Using the Code
这种方法涉及使用 Singleton 在客户端存储数据。Singleton 中的数据通过 WCF 客户端中的事件访问,因为客户端与 Singleton 位于不同的项目中。
为了使客户端能够从客户端缓存中检索数据,请检查事件是否不为 null,然后使用包含搜索参数以及包含传递结果回来的方式的自定义事件参数来触发该事件。如果本地未找到该对象,则客户端将向服务器发起调用以在那里找到它。
WCF 客户端方法,用于通过 ID 查找类别
// Event to hook up in the Singleton that will get the data from the local store
public event FindObjectByIdInvokedDelegate GetCategoryByIdInvoked;
public Category GetCategoryById(int id)
{
Category cat = null;
// Check to see if the event is hooked up
if (GetCategoryByIdInvoked != null)
{
// Create the event args with the id of the requested object
FindObjectByIdEventArgs args = new FindObjectByIdEventArgs(id);
// Fire the event to look up the data
GetCategoryByIdInvoked(this, args);
// Get the object that was found, if no object is found this should return null
cat = args.FoundObject as Category;
}
// If nothing was found locally, then go to the server
// to find the object from the database
if (cat == null)
{
cat = base.Channel.GetCategoryById(id);
}
return cat;
}
带有 WCF 客户端事件挂钩的 Singleton 类
public Client WcfClient
{
get{
if (wcfClient == null)
{
// Create new instance of the Client if necessary
wcfClient = new Client();
// Hook up event in the Client to find a category by an Id
wcfClient.GetCategoryByIdInvoked +=
new FindObjectByIdInvokedDelegate(wcfClient_GetCategoryByIdInvoked);
}
return wcfClient;
}
}
void wcfClient_GetCategoryByIdInvoked(object sender, FindObjectByIdEventArgs args)
{
// Look in the locally stored collection of Categories
// to find the specific category
foreach (Category cat in Categories)
{
// If we find the category then set the result in the
// event args to get passed back to the Client class
if (cat.CategoryID == args.SubjectId)
args.FoundObject = cat;
}
}
结论
这是一个非常简单的示例,但可以很容易地扩展到包含任何类型的数据。通过在大型智能客户端应用程序中执行此操作,我们通过减少对服务器的调用,看到了巨大的性能提升。我强烈建议任何希望提高智能客户端应用程序性能的人考虑实施类似此过程的方法。
历史
- 2008 年 1 月 31 日 - 初始版本