当在WCF
中接收Stream
并将其写入数据库表时,将数据写入数据库表时使用的缓冲区大小是多少,如何更改?
我使用的是.NET Framework 4.6和Microsoft SQL Server。
服务器
[ServiceContract(Name = "IUploadFileService")]
public interface IUploadFileService
{
[OperationContract]
void UploadFile(UploadFileMessage uploadFileMessage);
}
[MessageContract]
public class UploadFileMessage
{
[MessageBodyMember]
public Stream FileContents { get; set; }
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class UploadFileService : IUploadFileService
{
public void UploadFile(UploadFileMessage uploadFileMessage)
{
using (MyDbContext context = new MyDbContext())
{
DbConnection conn = context.Database.Connection;
ConnectionState initialState = conn.State;
try
{
if (initialState != ConnectionState.Open)
{
conn.Open();
}
using (DbCommand cmd = conn.CreateCommand())
{
// the FileContents field is a `varbinary(max)` data type
cmd.CommandText = "INSERT INTO [Files] (FileContents) VALUES (@FileContents)";
cmd.CommandTimeout = 0;
DbParameter parameter = cmd.CreateParameter();
parameter.ParameterName = "@FileContents";
parameter.DbType = DbType.Binary;
parameter.Size = -1;
parameter.Value = uploadFileMessage.FileContents; // what buffer size is used to read this Stream and write it to the database?
cmd.Parameters.Add(parameter);
cmd.ExecuteNonQuery();
}
}
finally
{
if (initialState != ConnectionState.Open)
{
conn.Close();
}
}
}
}
}
服务器配置
<?xml version="1.0" encoding="utf-8" ?>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IFileUploadService" closeTimeout="00:01:00" receiveTimeout="24.20:31:23.6470000" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" transferMode="Streamed">
<readerQuotas maxArrayLength="32505856" maxStringContentLength="32505856" />
<security mode="None">
<transport clientCredentialType="None" protectionLevel="None" />
<message clientCredentialType="None" />
</security>
</binding>
</netTcpBinding>
</bindings>
客户
private static void UploadFile()
{
EndpointAddress endpointAddress = new EndpointAddress("net.tcp://localhost:4502/FileUploadService");
NetTcpBinding binding = new NetTcpBinding(SecurityMode.None)
{
TransferMode = TransferMode.Streamed,
MaxBufferSize = int.MaxValue,
MaxReceivedMessageSize = int.MaxValue,
SendTimeout = TimeSpan.MaxValue
};
FileUploadServiceClient fileUploadServiceClient = new FileUploadServiceClient(binding, endpointAddress);
using (FileStream fileStream = new FileStream(@"c:test.bin", FileMode.Open)) // read buffer size is 4096 bytes by default
{
fileUploadServiceClient.UploadFile(fileStream);
}
}
是这些吗?
- 在用于在客户端上打开文件的
FileStream
中指定的默认值 - 客户端上的
NetTcpBinding.MaxBufferSize
- WCF 服务器配置中的
maxBufferSize
DbParameter.Size
,这是int.MaxValue
,因为它设置为-1
和可以在varbinary(max)
数据库字段中输入的最大字节数Network Packet Size
SQL Server 数据库中的配置设置- 网络上
MTU
值 - 以上所有值的最小值
谢谢。
Windows Communication Foundation (WCF( 传输支持两种传输消息的模式:
1.缓冲传输将整个消息保存在内存缓冲区中,直到传输完成。必须先完全传递缓冲消息,然后接收方才能读取它。
2.流传输将消息公开为流。接收方在消息完全传递之前开始处理消息。
我看到您使用第二种传输模式,流式处理,它可以通过消除对大内存缓冲区的需求来提高服务的可伸缩性。
为了防止拒绝服务攻击,WCF 公开了 MaxReceivedMessageSize 属性来限制传入消息的大小属性,因此它还限制处理消息时访问的最大内存量。单位以字节为单位设置,默认值为 65,536 字节。
有关流式消息传输的更多信息,请参阅以下链接:
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/streaming-message-transfer