我读了很多关于客户端应该关闭client.Close()
连接的事实的文章,所以不会超出WCF默认限制事实上,我有WCF WebGet操作,基本上只返回一个图像。
[ServiceContract(SessionMode = SessionMode.NotAllowed)]
[ValidationBehavior]
public interface IImagesService
{
[OperationContract(Name = "ImagesGet4")]
[WebGet(UriTemplate = "/Image/{partner}/{id}/{image}_{width}_{height}.jpg")]
Stream ImagesGet2(string partner, string id, string image, string width, string height);
}
在这种情况下,客户端是浏览器,无论我使用wcf配置做什么都无济于事。 maxConnections,maxReceivedMessageSize,maxBytesPerRead
和许多其他参数被最大化,但仍然没有运气。
编辑:
这是额外的代码:
服务调用的ImageGet
方法:
public Stream ImagesGet(string partner, string id, string image, string width = null, string height = null)
{
WSData.EventLogs.MinimalEventSource.Log.ClientIp("");
WSData.EventLogs.MinimalEventSource.Log.ServicePath("");
WSData.EventLogs.MinimalEventSource.Log.Message( DateTime.Now + " | " + partner );
bool cache;
var images = new Images();
var stream = images.ImagesGetStream(out cache, partner, id, image, width, height);
if (cache)
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Cache-Control", "public, max-age=604800");
WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.Today;
WebOperationContext.Current.OutgoingResponse.SetETag(id);
}
WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
OperationContext clientContext = OperationContext.Current;
clientContext.OperationCompleted += new EventHandler(delegate (object sender, EventArgs args)
{
if (stream != null)
stream.Dispose();
});
return stream;
}
上述方法调用的ImagesGetStream
方法是:
public Stream ImagesGetStream( out bool cache, string partner, string id, string image, string width = null, string height = null, string background = null )
{
string PARTNER = partner;
cache = true;
try
{
EventLogs.MinimalEventSource.Log.Load( 10, "DatabaseCall" );
var img = ImagesDL.GetImage( PARTNER, new PrimaryKey( id ) );
EventLogs.MinimalEventSource.Log.Unload( 13 );
EventLogs.MinimalEventSource.Log.Load( 14, "GettingImageDir" );
var imagesRoot = Path.Combine( BaseConfiguration.GetDocumentsSharedDirectory( PARTNER ), img.Url );
var isWatermarked = img.Group.Contains( "WEBES" ) == false && ( partner.ToUpper() == "ZG-ADRIAGATE1" || partner.ToUpper() == "LENIO-ADRIAGATE2" || partner.ToUpper() == "LENIO" );
EventLogs.MinimalEventSource.Log.Unload( 15 );
EventLogs.MinimalEventSource.Log.Load( 16, "ImageToStream" );
var stream = new FileStream( imagesRoot, FileMode.Open, FileAccess.Read, FileShare.Read );
EventLogs.MinimalEventSource.Log.Unload( 17 );
if (!string.IsNullOrEmpty(width))
{
var isBackground = !string.IsNullOrEmpty(background);
int widthp = 0;
int heightp = 0;
int.TryParse(width, out widthp);
int.TryParse(height, out heightp);
return ResizeImage(partner, stream, new Size(widthp, heightp), isBackground, img.Guest, isWatermarked, background);
}
else if(img.Group.Contains("WEBES") == false) {
Image imgToResize = Image.FromStream(stream);
if(imgToResize.Width > imgToResize.Height && imgToResize.Width > 2048 )
return ResizeImage(partner, stream, new Size(2048, 1536), false, img.Guest, isWatermarked, background);
else if (imgToResize.Width < imgToResize.Height && imgToResize.Height > 2048)
return ResizeImage(partner, stream, new Size(1536, 2048), false, img.Guest, isWatermarked, background);
else if (imgToResize.Width == imgToResize.Height && imgToResize.Height > 2048)
return ResizeImage(partner, stream, new Size(2048, 2048), false, img.Guest, isWatermarked, background);
}
return isWatermarked ? WatermarkingImage( partner, stream, img.Guest, isWatermarked ) : stream;
}
catch ( Exception )
{
cache = false;
return new FileStream( AppPath + @"\App_Resorces\NoImage.jpg", FileMode.Open, FileAccess.Read, FileShare.Read );
}
}
这是配置的相关部分:
<service name="WSTraveller.ImagesService" behaviorConfiguration="ServiceBehavior">
<endpoint address="soap" binding="basicHttpBinding" behaviorConfiguration="soapBehavior" contract="WSTraveller.IImagesService" bindingConfiguration="soapBinding" bindingName="soapBinding" bindingNamespace="http://ws.adriagate.com/TRWS/ImagesService.svc/soap"/>
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="poxBehavior" contract="WSTraveller.IImagesService" bindingConfiguration="webBinding" bindingName="webBinding" bindingNamespace="http://ws.adriagate.com/TRWS/ImagesService.svc/pox"/>
</service>
...
<basicHttpBinding>
<binding name="soapBinding" closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" messageEncoding="Text">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
<security mode="None"/>
</binding>
</basicHttpBinding>
答案 0 :(得分:1)
我的两分钱..检查一下这是否对你有帮助:
1)尝试使用gzip流左右压缩图像,在我们的项目中,我们必须使用wcf在线上发送大量数据集,因此我们习惯于压缩然后将其发送出来。
2)如果数据库是瓶颈,那么你可以使db调用异步并使用队列机制来存储结果,并且wcf客户端请求会尝试并定期将结果出列。
答案 1 :(得分:1)
在回收应用程序池之前,请进行内存转储。如果你有Visual Studio Enterprise,你可以在一个漂亮的gui中打开转储,并查看进程中所有.NET线程的堆栈跟踪。由于应用程序不再响应请求,因此大多数堆栈跟踪很可能位于同一位置,这将告诉您代码中的问题所在。然后你知道在哪里集中精力。
答案 2 :(得分:1)
来自MSDN:
默认情况下,HTTP,TCP / IP和命名管道传输使用缓冲的消息传输。
缓冲传输将整个消息保存在内存缓冲区中,直到传输完成。
由于您尚未在配置中指定使用 Streamed ,因此它使用缓冲作为传输模式。因此,由于存储在内存中的大量文件(取决于数量或请求),您的进程可能因内存不足而运行。
请进行更改,然后重试。我认为这将解决问题。