ASP-страничка прекрасно рендерит картинку на локальной машине (Windows7, VS Development Server или IIS-Express)
и не хочет это делать, когда работает у хостера
http://flag.somee.com/RenderInfo.aspx
(проверил на parking.ru - не поддерживается .NET Framework 4.0)
Для серверного рендеринга используется WPF. Визуализируется Grid с двумя потомками: Rectangle и Button. Оба они отрисовываются в png-файл без проблем. Когда же вместо Button процедура получает Viewport3D, она его в упор не видит.
P.S. Процедура рендеринга выглядит примерно так:
private RenderTargetBitmap CreateFlagImg(FrameworkElement myCanvas, ...)
{
FlagCanvas.UpdateLayout();
FlagCanvas.Measure(new Size(FlagCanvas.Width, FlagCanvas.Height));
FlagCanvas.Arrange(new Rect(new Size(FlagCanvas.Width, FlagCanvas.Height)));
RenderTargetBitmap rtb = new RenderTargetBitmap(..., PixelFormats.Pbgra32);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext ctx = dv.RenderOpen())
{
VisualBrush vb1 = new VisualBrush(myCanvas);
ctx.DrawRectangle(vb1, ...);
}
rtb.Render(dv);
return rtb;
}


Обнаружил на форуме Microsoft "товарища по несчастью" - Render image of WPF viewport3D on windows server 2008 (off-screen) - http://social.msdn.microsoft.com/Forums/en-US/winserver2008appcompatabilityandcertification/thread/82ec69bc-3d71-4eee-bf06-4024121fd9a3
ОтветитьУдалитьЗа два месяца никто на его вопрос не ответил :-(
Может дело в том, что у потока, который рендерит, должен стоять атррибут [STAThread]
ОтветитьУдалитьДа, без этого атрибута при попытке создать Viewport3D возникает исключение: "Вызывающим потоком должен быть STA, поскольку этого требуют большинство компонентов UI".
УдалитьПоэтому ASP-страничка создает новый STA-поток, передает ему параметры через конструктор класса и ждет, пока STA-поток создаст Viewport3D, отрендерит картинку и запишет результат в jpg-файл.
string sId = "01_02_03";
autoEvent = new AutoResetEvent(false);
RadFlagThread tws = new RadFlagThread(sId, -1,
new RadFlagThread.ExampleCallback(ResultCallback));
Thread t = new Thread(new ThreadStart(tws.GetFlagFileName_STA));
t.SetApartmentState(ApartmentState.STA);
t.Start();
autoEvent.WaitOne();
Image1.ImageUrl = sOut;
где-то так...
Еще одно обсуждение этой проблемы на форуме Microsoft - RenderTargetBitmap issue with blank images under ASP.net - http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/e1de73b5-890b-43c6-975d-4951e7cb70c1/
ОтветитьУдалитьПо их мнению, изображение может быть пустым если процесс, в котором выполняется рендеринг, не "привязан" к консоли Windows Server.
Вторая гипотеза (моя) - на сервере установлена "слабая" видеокарта, версия DirectX ниже 9.0., поэтому 3D-рендеринг не выполняется или выполняется так долго, что "не укладывается" в разумное время и происходит выход по таймауту без возникновения ошибки, но и без отрендеренной картинки.
Измерял время рендеринга. На моей машине все предсказуемо: (120006 / 230014)
ОтветитьУдалитьТ.е. присутствие в сцене Viewport3D почти удваивает время рендеринга.
На сервере - очень странно
1) время - константа = 156250 (15,625 миллисекунд)
2) это время расходуется или на первый рендеринг, или на второй, или на каждый из них:
А: (156250 / 0)
B: (0 / 156250)
C: (156250 / 156250)
причем, при повторении расчета (кнопка на странице) идет редко нарушаемое чередование: C, A, B, C, A, B, ...
Теоретически, IIS на шаред-хостинге и должен квантовать выделяемые отдельным процессам периоды времени. В то же время, время рендеринга = 0 как-то настораживает...