I'm developing a simple ASP.NET handler that returns image that is rendered using XAML on server side.
The problem that after stress testing picture disappears from returned image (but empty image is still returned). The picture here is XAML canvas (I put it to the bottom of the message) with different shapes and glyphs (rectangles with gradient fill, lines and text with digits).
I tested on Windows 2003 (two processors, four processors), IIS 6.0, .NET 2.0, WinFX RC (February CTP), emulated 250 concurrent users.
I have the following code:
public MemoryStream CreateImageStream(String xaml)
{
object obj = System.Windows.Markup.XamlReader.Load(new XmlTextReader(new StringReader(xaml)));
UIElement canvas = (UIElement)obj;
canvas.Arrange(new Rect(new System.Windows.Point(0, 0), new System.Windows.Size(300, 300)));
canvas.UpdateLayout();
MemoryStream mem = new MemoryStream();
System.Windows.Media.Imaging.RenderTargetBitmap bmp = new System.Windows.Media.Imaging.RenderTargetBitmap(
(int)200, (int)100, 96, 96,
System.Windows.Media.PixelFormats.Pbgra32
);
bmp.Render(canvas);
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
encoder.Save(mem);
return mem;
}
Then I write resulting MemoryStream to Response.OutputStream in ASP.NET handler. It works fine if navigate to URL in IE.
I setup load tests for 250 users (each test is just get the same image in PNG format from the site).
After 1 - 2 minutes (I'm using IE to check this) - picture disappears from returned image.
Actions undertaked:
1. I setup remote debugging in VS 2005 and debug the code when the system comes to error state. There are no any exceptions in the code. Everything seems working fine (I went through RenderTargetBitmap, BitmapVisualManager, Renderer, some other code that is in PresentationCore, PresentationFramework and WindowsBase assemblies). Wasn't able to debug MilCore.dll because debug symbols are not available yet.
2. If AppDomain is reloaded (by modifying web.config for instance) - problem is disappeared, everything works fine again (for a while).
3. There is no memory leaks, memory is enough on the machine.
4. Set affinity... to one processor only doesn't help.
Guys from Microsoft please help! We are considering of using SVG or XAML for server side rendering and if this problem will not be resolved soon probably I'll be forced to use SVG. But I like XAML more! :)
Regards,
Andrey
Here is XAML that I used:
<Canvas Width="372" Height="64.8" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Rectangle Canvas.Left="0" Canvas.Top="0" Height="20" Width="200" >
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FF3366FF" Offset="0" />
<GradientStop Color="#FFFFFFFF" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Canvas.Left="0" Canvas.Top="5" Height="10" Width="180">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="Red" Offset="0" />
<GradientStop Color="Black" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Stroke="Red" Canvas.Left="165" Canvas.Top="2" Fill="Black" Height="16" Width="5"/>
<Line Stroke="Blue" X1="0" Y1="20" X2="0" Y2="25"/>
<Line Stroke="Blue" X1="20" Y1="20" X2="20" Y2="25"/>
<Line Stroke="Blue" X1="40" Y1="20" X2="40" Y2="25"/>
<Line Stroke="Blue" X1="60" Y1="20" X2="60" Y2="25"/>
<Line Stroke="Blue" X1="80" Y1="20" X2="80" Y2="25"/>
<Line Stroke="Blue" X1="100" Y1="20" X2="100" Y2="25"/>
<Line Stroke="Blue" X1="120" Y1="20" X2="120" Y2="25"/>
<Line Stroke="Blue" X1="140" Y1="20" X2="140" Y2="25"/>
<Line Stroke="Blue" X1="160" Y1="20" X2="160" Y2="25"/>
<Line Stroke="Blue" X1="180" Y1="20" X2="180" Y2="25"/>
<TextBlock Text="0" FontFamily="Arial" FontSize="8" Canvas.Left="0" Canvas.Top="28" />
<TextBlock Text="1" FontFamily="Arial" FontSize="8" Canvas.Left="18" Canvas.Top="28" />
<TextBlock Text="2" FontFamily="Arial" FontSize="8" Canvas.Left="38" Canvas.Top="28" />
<TextBlock Text="3" FontFamily="Arial" FontSize="8" Canvas.Left="58" Canvas.Top="28" />
<TextBlock Text="4" FontFamily="Arial" FontSize="8" Canvas.Left="78" Canvas.Top="28" />
<TextBlock Text="5" FontFamily="Arial" FontSize="8" Canvas.Left="98" Canvas.Top="28" />
<TextBlock Text="6" FontFamily="Arial" FontSize="8" Canvas.Left="118" Canvas.Top="28" />
<TextBlock Text="7" FontFamily="Arial" FontSize="8" Canvas.Left="138" Canvas.Top="28" />
<TextBlock Text="8" FontFamily="Arial" FontSize="8" Canvas.Left="158" Canvas.Top="28" />
<TextBlock Text="9" FontFamily="Arial" FontSize="8" Canvas.Left="178" Canvas.Top="28" />
</Canvas>

XAML, RenderTargetBitmap - picture disappears from image after load testing
rusk50
"Failed" I mean - picture dissapears from the image. So image is generated successfully and HTTP Request/Response is also OK.
Image with length of 451 is just visually empty. (But it is still normal PNG image)
I stress test application in MS VS 2005 for Testers - I use a load test with 250 concurrent users. (It just send the same HTTP GET Request to server). Average request/sec is 101. (I attached picture with Load Test results to zip file that I sent to you by mail).
I attached the XAML code to my first message in current thread (http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=350088&SiteID=1)
I sent to you email with attached images, statistics, load tests results and XAML file.
Regards,
Andrey
Porko
But why this could happen Any thoughts
Restarting of AppDomain helps - so, what kind of WPF caches/data could change to corrupted/bad state
stayfitsoftware
I think I'm having the same problems you are, sometimes my png files are the right size but empty.
I think I got lucky, I have some paths i'm saving to a file, and if I try what you are trying it comes through empty. If I put the paths in a border, measure/arrange the border as well, and render the border, everything comes through fine. Does this work for you
LarryWho
Let’s drill into the results a bit further…
The one where there is no picture in the image is curious to me.
When you say “failed” in these remarks “The first couple failed requests were after 2000 requests:” and “After 17000 requests almost all of them "failed":”, what exactly do you mean Did the file get saved to the server If so, is the image blank
When you make the 17000 requests, are any of them concurrent or are they all subsequent calls to the page
If you wouldn’t mind sending me the code snippet of XAML that you’re rendering to the RenderTargetBitmap, that would be wonderful. I can take a look at it a bit further here. My email robertwl_at_microsoft_dot_com.
Thanks,
Robert.
venkyweb
I don't know for sure, but it may be a similar problem to what Charles Petzold encountered here: http://www.charlespetzold.com/blog/2006/02/230940.html
Sam
srinivas vasireddy
Could the problem be in these two lines:
canvas.Arrange(new Rect(new System.Windows.Point(0, 0), new System.Windows.Size(300, 300)));canvas.UpdateLayout();
According to the docs (http://windowssdk.msdn.microsoft.com/library/default.asp url=/library/en-us/cpref28/html/M_System_Windows_UIElement_Measure_1_7183a95b.asp) you shouldn't have to call UpdateLayout. The docs seem to suggest trying a call to canvas.Measure before canvas.Arrange instead.
cbaldo1
Please be aware...we have not architected WPF with the goal of running well on a server.
-Rob Relyea
WPF, PM
http://longhornblogs.com/rrelyea
rebus
I had posted a message concerning why I added UpdateLayout to this code. (http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=337347&SiteID=1)
The problem was - I had memory leaks if I didn't call UpdateLayout. Documentation you provided states:
"Layout updates happen asynchronously, such that the main thread is not waiting for every possible layout change.", "When updating layout, the Measure queue is emptied first, followed by the Arrange queue. An element in the Arrange queue will never be arranged if there is an element in the Measure queue".
In my scenario main thread never emptied Arrange/Measure queues. Thats why I call UpdateLayout.
Anyway, I removed UpdateLayout, added Measure call - it doesn't help...
saleem145
I need to do something similar... what is the status of this
Kevin
Tirumala
Yes, sure, I'm willing to do anything that could help to solve the issue.
What I did:
I store all response streams (that differs by size/content) with PNG images to files. So I have 13 different files. And also I stored statistics at each 1000 requests, so for instance after 1000 requests I have:
Length: 3803, count: 850
Length: 3808, count: 40
Length: 3798, count: 1
Length: 3790, count: 2
Length: 3804, count: 92
Length: 3495, count: 1
Length: 3789, count: 2
Length: 3794, count: 7
Length: 3786, count: 1
Here is Length - image length, count - how many times image with this contcrete length and concrete content was generated.
The first couple failed requests were after 2000 requests:
Length: 3801, count: 8
Length: 3803, count: 1676
Length: 3808, count: 74
Length: 3798, count: 3
Length: 3790, count: 2
Length: 3804, count: 211
Length: 451, count: 2 --- there is no picture in this image.
Length: 3495, count: 1
Length: 3787, count: 1
Length: 3789, count: 3
Length: 3802, count: 1
Length: 3794, count: 15
Length: 3786, count: 1
After 17000 requests almost all of them "failed":
Length: 3801, count: 10
Length: 3803, count: 2318
Length: 3808, count: 107
Length: 3798, count: 4
Length: 3790, count: 2
Length: 3804, count: 302
Length: 451, count: 14220
Length: 3495, count: 1
Length: 3787, count: 2
Length: 3789, count: 3
Length: 3802, count: 2
Length: 3794, count: 27
Length: 3786, count: 1
I have PNG images and statistics files ready. I didn't find how to attach the files to this message, so if you want to look at them, please tell me how I should upload them to you.
Thank you in advance,
Andrey
The Triggerman
Vincent Vouillon