gpt4 book ai didi

c# - 在高并发 WCF Web 服务中使用实例和单例

转载 作者:行者123 更新时间:2023-11-30 12:10:34 25 4
gpt4 key购买 nike

我正在开发一个 WCF Web 服务,它根据 string providerCode 从多个数据库之一返回信息。

在最高级别,服务调用 StaticBroker 类,它检查 providerCode 并返回 DataManager 的适当子类,比方说我的数据管理器。该服务然后调用 MyDataManager.getVehicleFetcherForStop(),它返回类 VehicleInfoFetcher 的实例,用于获取信息。

我对这一切都很陌生,我想我的架构可能有误。这是我现在如何执行此操作的代码(已简化):

Service.svc.cs

// Public-facing web service method
public string getRealtimeInfo(String stopID, string providerCode = "UK")
{
DataManager dm = StaticBroker.Instance.dataManager(stopID);
return dm.getUpcomingVehicleInfoNow(primaryCode);
}

静态代理

public sealed class StaticBroker
{
UKDataManager ukDataManager = null;

// Create one instance of each data manager when the Web Service is started,
// to save memory
private StaticBroker()
{
ukDataManager = new UKDataManager();
}

public DataManager dataManager(string providerCode)
{
if (providerCode.Equals(UKDataManager.DEFAULT_PROVIDER_CODE))
return ukDataManager;
// else if...
}

// Most singleton stuff snipped out
private static readonly StaticBroker instance = new StaticBroker();
}

UKDataManager

public class UKDataManager : DataManager
{
public const string DEFAULT_PROVIDER_CODE = "UK";

public string getUpcomingVehicleInfoNow(string stopID)
{
VehicleInfoFetcher infoFetcher;
if ( shouldCheckDB(stopID))
VehicleInfoFetcher infoFetcher = new DatabaseVehicleInfoFetcher("UK");
else
fetcher = new UKLiveVehicleInfoFetcher();

return fetcher.getVehicleInfo(primaryCode).Result; // This is an async method, but we wait for the result
}
}
}

如您所见,我有一个 StaticBroker 的单例,它本身只存储每种类型的 DataManager 的一个实例。最后,在 DataManagers 中,创建了执行实际工作的类 SomeVehicleFetcher 的实际实例。

这是一种明智的做法吗?或者当 Web 服务的并发使用率很高时,这些单例和共享实例是否会导致问题?我担心创建大量新实例可能会导致内存问题。如您所见,我不太了解 Web 服务中应用程序的生命周期/内存周期是如何工作的。

最佳答案

您正在尝试使用您不认为正确或需要的设计来解决假设性问题(“可能导致内存问题”)。此外,ADO.NET 有大量优化来处理数据库连接性能。

这只会带来更多的工作和更多的测试难题(您将如何隔离依赖于此代理的代码?)。

参见反模式:

过早的优化,不是这里发明的

编辑:

public interface IVehicleInfoRetriever {
VehicleInfoResponse getVehicleInfo(string primaryCode);
}

public class DataManager<TVehicleInfoFetcher>
where TVehicleInfoFetcher : class, new(), IVehicleInfoRetriever
{

private string _providerCode;

public DataManager() : this("UK") { }

public DataManager(string providerCode) {
_providerCode = providerCode;
}

public string getUpcomingVehicleInfoNow(string stopID)
{
VehicleInfoFetcher infoFetcher;
if ( shouldCheckDB(stopID))
VehicleInfoFetcher infoFetcher = new DatabaseVehicleInfoFetcher(_providerCode);
else
fetcher = new TVehicleInfoFetcher();

return fetcher.getVehicleInfo(primaryCode).Result; // This is an async method, but we wait for the result
}
}

}

像这样的东西消除了对“经纪人”的需要。

此外,您称为“Broker”的类更像是一个工厂,工厂已经失宠,因为它们允许在杂草中而不是在顶部指定依赖注入(inject),并且它们为单元测试一项复杂的任务。

当然,不同 DataManager 之间的差异可能比您展示的更多。如果是这种情况并且它们不能集中,那么我建议您调查许多可用的控制反转容器之一(想到 AutoFac、Unity、CaSTLe Windsor)。这些容器将根据提供程序代码的运行时值在最顶层保留使用哪种风格的 DataManager 的逻辑。

关于c# - 在高并发 WCF Web 服务中使用实例和单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17996711/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com