среда, 25 июля 2012 г.

Проблема рендеринга на шаред хостинге (добавлено)


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;
}

5 комментариев:

  1. Обнаружил на форуме 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
    За два месяца никто на его вопрос не ответил :-(

    ОтветитьУдалить
  2. Может дело в том, что у потока, который рендерит, должен стоять атррибут [STAThread]

    ОтветитьУдалить
    Ответы
    1. Да, без этого атрибута при попытке создать 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;

      где-то так...

      Удалить
  3. Еще одно обсуждение этой проблемы на форуме 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-рендеринг не выполняется или выполняется так долго, что "не укладывается" в разумное время и происходит выход по таймауту без возникновения ошибки, но и без отрендеренной картинки.

    ОтветитьУдалить
  4. Измерял время рендеринга. На моей машине все предсказуемо: (120006 / 230014)
    Т.е. присутствие в сцене Viewport3D почти удваивает время рендеринга.
    На сервере - очень странно
    1) время - константа = 156250 (15,625 миллисекунд)
    2) это время расходуется или на первый рендеринг, или на второй, или на каждый из них:
    А: (156250 / 0)
    B: (0 / 156250)
    C: (156250 / 156250)
    причем, при повторении расчета (кнопка на странице) идет редко нарушаемое чередование: C, A, B, C, A, B, ...
    Теоретически, IIS на шаред-хостинге и должен квантовать выделяемые отдельным процессам периоды времени. В то же время, время рендеринга = 0 как-то настораживает...

    ОтветитьУдалить

Можете оставить комментарий: