2008-12-24 11 views
16

De acuerdo con MSDN, no es una buena idea usar clases dentro del espacio de nombres System.Drawing en un Servicio de Windows o Servicio ASP.NET. Ahora estoy desarrollando una biblioteca de clases que podría necesitar acceder a este espacio de nombres particular (para medir fuentes) pero no se puede garantizar que el proceso de host no sea un servicio.System.Drawing en servicios de Windows o ASP.NET

Ahora hay un método menos óptimo al que puedo recurrir si System.Drawing no está disponible, pero si es posible, preferiría usar clases en System.Drawing. Entonces, lo que me gustaría hacer es determinar a runtume si System.Drawing es seguro o no, y si lo es, usarlo; de lo contrario, volver a la opción subóptima.

Mi problema es: ¿Cómo puedo detectar si System.Drawing es seguro de usar?

Creo que debería ya sea

  • detectar si el proceso actual es un servicio de Windows o servicio ASP.NET
  • detectar si GDI está disponible
  • O tal vez hay una manera de pedir Sistema .Drawing.dll sí mismo si es seguro de usar

Desafortunadamente, no puedo encontrar una manera de implementar ninguno de estos enfoques. ¿Alguien tiene alguna idea?

+0

¿Por qué necesita verificar las cosas relacionadas con la fuente? Como entiendo, los servicios de Windows no tienen UI. Por favor ayuda a entender el motivo. – shahkalpesh

+0

Sin entrar demasiado en los detalles, esta biblioteca de clases genera informes, que pueden ser enviados potencialmente por el proceso de host en correos electrónicos. Una de las funciones necesita medir el ancho representado de una cadena. El punto es que podría mostrarse en otras computadoras, no en el servidor en sí. –

+0

He encontrado que GDI + (System.Drawing) es seguro de usar, siempre que deseche correctamente todos los objetos desechables, tenga un correcto manejo de errores y [evite todos los errores] (http://nathanaeljones.com/163/20 -image-resizing-pitfalls /). Con sitios web de 10K-60K ejecutando [la creación de imágenes.net library (que, de forma predeterminada, usa GDI + para cambiar el tamaño de las imágenes dinámicamente)] (http://imageresizing.net), todavía no ha habido un solo problema de estabilidad relacionado con el uso de System.Drawing. Sin embargo, a menos que use System.Drawing correctamente, podría * fácilmente * crear problemas de estabilidad. –

Respuesta

18

Para aclarar cualquier confusión, System.Drawing hace trabajo bajo ASP.NET y Servicios, es sólo que no apoyaron . Puede haber problemas con alta carga (agotamiento de recursos no administrados), pérdida de memoria o de recursos (patrones de disposición mal implementados o denominados) y/o diálogos que aparecen cuando no hay un escritorio para mostrarlos.

Las pruebas se ocuparán de esto último, y la supervisión lo alertará de lo primero.Pero, si tiene un problema, no espere poder llamar a PSS y pedir una solución.

Entonces, ¿cuáles son sus opciones? Bueno, si no necesita una ruta completamente compatible, y no espera una carga extrema, mucha gente ha ignorado la advertencia de MSDN y ha utilizado System.Drawing con éxito. Algunos de ellos han sido mordidos, pero hay mucho más éxito que historias de fracaso.

Si quiere algo compatible, entonces necesita saber si se está ejecutando interactivamente o no. Personalmente, probablemente dejaré que la aplicación de alojamiento configure una bandera no interactiva en algún lugar u otro. Después de todo, la aplicación se encuentra en la mejor posición para determinar si se encuentran en un entorno alojado y/o si desean arriesgar los problemas de GDI +.

Pero, si desea detectar automágicamente su entorno, supongo que hay peores respuestas que las que se ofrecen right here on SO para un servicio. Para resumir, puede verificar EntryAssembly para ver si hereda de ServiceBase o intentar acceder a System.Console. Para ASP.NET, en la misma línea, detectar HttpContext.Current debería ser suficiente.

que había pensar que habría un administrado o p/invocar manera de buscar un escritorio (que en realidad es el factor decisivo en todo esto, creo) y/o algo fuera del dominio de aplicación, que haría pista usted adentro. Pero no estoy seguro de cuál es, y MSDN es menos que esclarecedor en él.

Editar: Trolling MSDN, recordé que en realidad es un Window Station (que aloja un escritorio) que es el punto importante aquí. Con esa información, pude encontrar GetProcessWindowStation() que devuelve un identificador a la estación de ventana actual. Si pasa ese identificador al GetUserObjectInformation() obtendrá una estructura USEROBJECTFLAGS que debería tener un dwFlags con WSF_VISIBLE si tiene un escritorio visible.

O bien, EnumWindowsStations le dará una lista de las estaciones que podría verificar: WinSta0 es la interactiva.

Pero, sí, sigo pensando que sólo tener la aplicación establece una propiedad o algo es la ruta mucho más fácil ....

de nuevo Edit: 7 años más tarde, consigo puesta al tanto en Environment.UserInteractive donde MS does the exact GetProcessWindowStation dance Describí lo anterior para ti ... Aún así, recomiendo delegar en la aplicación de alojamiento (pueden querer el camino más rápido, pero un poco más arriesgado de System.Drawing), pero UserInteractive parece ser un buen valor por defecto sin tener que pinvoke usted mismo

1

En su lugar, podría usar TextRenderer. Sé que es extraño usar algo de System.Windows.Forms en ASP.NET, pero no parece tener la misma advertencia acerca de no ser compatible con ASP.NET. He usado tanto TextRenderer como Graphics.MeasureString para medir cadenas en aplicaciones ASP.NET, para que ambos funcionen. Nunca había visto la advertencia sobre System.Drawing no siendo aconsejable en ASP.NET.

TextRenderer es mucho más lento que Graphics.MeasureString, FWIW.

+0

System.Drawing está disponible en aplicaciones web ASP.NET, pero no en servicios web ASP.NET. –

+0

No estoy seguro de que te sigo. System.Drawing está disponible desde aplicaciones web ASP.NET y servicios web ASP.NET. Solo lo probé para asegurarme. – MusiGenesis

+0

De hecho está disponible, es solo que no se recomienda usarlo. Consulte http://msdn.microsoft.com/en-us/library/system.drawing.aspx (busque una gran caja azul) –

-1

Es posible que pueda copiar System.Drawing.dll en el contenedor de su aplicación y luego usarlo de esa manera. Eso podría garantizar su disponibilidad.

clic Justo a la derecha en la referencia en la aplicación y cambiar la opción para copia local a cierto.

se me puede entender la pregunta, aunque ...

+0

El problema no es la disponibilidad, ya que System.Drawing.dll es parte de .NET Framework. El problema es que sin GDI presente, no puede funcionar correctamente. –

+0

Derecha - Entiendo ahora – Hugoware

0

Podría ser algo que ver con el subsistema GDI necesidad de un subproceso STA. Si este es el caso, investigue especificando ASPCOMPAT = TRUE en su directiva @PAGE para la página aspx involucrada. Esto ejecutará la página aspx en un hilo STA, IIRC.

-Oisin

4

Aunque oficialmente no es compatible, he usado las clases System.Drawing extensivamente en un servidor web de gran volumen (tanto la aplicación web como los servicios web) durante años sin que haya problemas de rendimiento o fiabilidad.

Creo que la única manera de determinar si el código es seguro de usar es probar, supervisar y ajustar cualquier objeto con recursos externos al usar declaraciones {}.

Cuestiones relacionadas