我有一个使用WebServices将数据库记录(作为数组)发送到客户端的应用程序,但即使只发送1000条记录,它似乎也很慢。
服务器在IIS 7上运行,客户端是WPF应用程序。基本上,我如何加快速度。我是否必须编写自定义压缩类或代码?是否只有我在IIS服务器和/或客户端配置文件上打开/关闭的设置?现在返回这1000条记录大约需要4-7秒。因此,当我们绑定到可能返回10,000 - 40,000条记录的表时,我不希望用户在那里等待数分钟。
以下是代码示例:
Foo.svc:
namespace Foo.Server
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public sealed class FooService : IFoo
{
public SelectRecordsResponse SelectRecords(SelectRecordsRequest request)
{
//I tested to ensure that this isn't my bottleneck
FooBar[] records = ...; //Stores 1000 records
return new SelectRecordsResponse(records);
}
}
}
FooCommon.cs:
namespace Foo
{
[ServiceContract(Namespace = "http://www.company.com/Services/Foo", ConfigurationName = "IFoo")]
[ServiceKnownType(typeof(AbstractEntity))]
[XmlSerializerFormat(SupportFaults = true, Style = OperationFormatStyle.Document, Use = OperationFormatUse.Literal)]
public interface IFoo
{
[OperationContract(Action = "http://www.company.com/Services/Foo/SelectRecords",
ReplyAction = "http://www.company.com/Services/Foo/SelectRecordsReply",
Name = "SelectRecords")]
[ServiceKnownType(typeof(FooBar))]
[return: MessageParameter(Name = "Response")]
SelectRecordsResponse SelectRecords([MessageParameter(Name = "Request")]SelectRecordsRequest request);
}
[MessageContract(WrapperName = "SelectRecordsRequest", WrapperNamespace = "http://www.company.com/Services/Foo/", IsWrapped = true)]
public sealed class SelectRecordsRequest
{
public SelectRecordsRequest()
{
}
}
[MessageContract(WrapperName = "SelectRecordsResponse", WrapperNamespace = "http://www.company.com/Services/Foo/", IsWrapped = true)]
public sealed class SelectRecordsResponse
{
public SelectRecordsResponse()
{
Init();
}
public SelectRecordsResponse(FooBar[] records = null)
{
Init(records);
}
private void Init(FooBar[] records = null)
{
Records = records ?? new FooBar[0];
}
[MessageBodyMember(Namespace = "http://www.company.com/Services/Foo/", Order = 0, Name = "Records")]
[XmlArray(ElementName = "SelectRecordsArray", Form = XmlSchemaForm.Qualified)]
[XmlArrayItem(typeof(FooBar), ElementName = "SelectRecordsFooBar", Form = XmlSchemaForm.Qualified, IsNullable = true)]
private FooBar[] Records { get; set; }
}
}
FooClient.cs:
namespace Foo.Client
{
public interface IFooChannel : IFoo, IClientChannel
{
}
public sealed class FooClient : ClientBase<IFoo>, IFoo
{
public FooClient(String endpointConfigurationName) :
base(endpointConfigurationName)
{
}
public FooBar[] SelectRecords()
{
SelectRecordsRequest request = new SelectRecordsRequest();
SelectRecordsResponse response = ((IFoo)(Client)).SelectRecords(request);
return response.Records;
}
SelectRecordsResponse IFoo.SelectRecords(SelectRecordsRequest request)
{
return Channel.SelectRecords(request);
}
}
}
答案 0 :(得分:2)
很可能,您的性能瓶颈是SelectRecordsResponse对象的序列化和反序列化。我可以提供几种方法来加快速度,从最小到最困难:
答案 1 :(得分:0)
您是否考虑使用适用于WCF的Microsoft Synchronization Services?
我过去曾使用它将数据同步到客户端,直到具有相似数量记录的服务器。它允许您根据特定条件过滤数据,并允许增量下载。
然而,即使使用同步服务,我也注意到在同步大量数据时会出现大幅减速。这是因为默认情况下数据被序列化为Xml,我使用binary encoder解决了这个问题。
答案 2 :(得分:0)
似乎减少分配时间的最佳方法是在评论中提出建议,即对数据进行分页,以便减少发送量。我同意使用XML序列化之外的东西会加快速度,但还不够。此外,使用其他序列化是不可接受的,因为我们不得不使用互操作序列化方法,以防我们改为使用Java客户端。