Luis, espero que este nuevo crosspost que vas a hacer desde luisguerrero.net sea con todos los éxitos.
A la espero tus post.
Saludos,
Fer Antivero.-
Bienvenido :)
Bienvenido!
Bienvenido titán!
Welcome, será un placer trabajar con una persona de tu calidad, estoy seguro de que aprenderé mucho de ti y que haremos cosas geniales en nuestro equipo.
Saludos
ESTRA + O -
Excelente, sigue con ello :D
Un saludo.
Welcome Home!
Gracias!!
Gracias a todos por la bienvenida, espero que hagamos muchas cosas juntos !!
Muchísimo ojo: el SP1 del .NET 3.5 y del Visual Studio 2008 continua en BETA.
Es un producto BETA, y podría no funcionar del todo bien (o más bien peor de lo que lo hacen las versiones finales).
Creo que deberías decirlo en la entrada para no llevar a engaño a los lectores...
:-)
Hola tocayo,
Bienvenido a geeks.ms!
Un saludo desde Andorra,
Muy bueno, sigue con ello :D
es un excelente curso, podrias subir toda la compilacion en un solo zip a la red, para poder descargarlo, de antemano gracias. o mandarmelo por correo: ernestomdzd@hotmail.com, gracias.
Luis, no deja de ser curioso que todo el mundo hable de la novedad de los procesos por pestaña... novedad que ha incorpora la beta 2 de IE...
Sobre lo costoso de crear nuevos procesos, pues es cierto, pero no es lo mismo tener un proceso por pestaña que por petición a un CGI... yo no creo que sea tan dañino.
La verdad es que me he tragado todo el comic de Google sobre la castaña esta de Chrome... y tampoco veo innovación alguna por ningún sitio, comparto tu opinión...
Otra cosa es que la gente considere que ponder las pestañas arriba y el un logo tipo Google es innovar...
Hola Luis,
Siento decirte que Google no es el único que tiene este modelo de aislamiento de tabs. IE 8, lo incluye. Exactamente no se la diferencia, pero IE 8 a diferencia de Google si reutiliza, optimiza y agrupa tabs por proceso de tal forma que cada proceso mantiene x tabs, pero estando aislado del resto.
En mi blog he hablado del tema, pero nunca desde el punto de vista de si es buena práctica o no, siempre del resultado al usuario.
Un saludo :)
la verdad esque este es el primer post de mis feeds que habla sin euforia, y se dedica a hacer un análisis un poco más de cabeza fría. Felicitaciones.
Por otro lado, he experimentado con el browser este, y la verdad es bueno, supongo que debido al webkit que usan.
En fin, entiendo los reparos que explicas sobre los procesos y el reuso de ellos, y bueno, que se le va a hacer, si termina funcionando mejor que ie7 y firefox (que es lo que ha pasado hasta ahora) entonces ie8 tiene una bara que alcanzar.
Quizas no sea tan barbaro, si finalmente termina funcionando.
Ahora que veo el comentario de Rodrigo, estamos de acuerdo, innovar han innovado poco.
La novedad la podemos ver en la interfaz simple y fluída (aun que no innovación) y donde si podemos ver innovación es la máquina virtual de JavaScript, V8. Pero promete mucho y no se donde ver realmente como afecta esto.
El modelo de aislamiento de pestañas, como dice Rodrigo no lo veo tan mal, pero como te dije en el comentario anterior, nunca lo analice pensando en las prácticas.
La pestaña inicial es una copia a Opera.
Incluso en el tema de la presentación han ido hacia atrás. No tiene ni un simple Zoom.
Hasta la desinstalación me parece una burla, dice: "¿Estás seguro de que deseas desinstalar Google Chrome? (Es que hemos hecho algo mal?)".
Me parece un movimiento de marketing.
"... me parece que esta solución de los “ingenieros” de software de google, es la más obvia, cutre y sobre todo la más fácil."
Pues es ni más ni menos que la misma mismita que va a implementar IE8 :-P
Además hasta donde yo sé, varios procesos pueden compartir una misma instancia de una DLL.
Y sinceramente yo prefiero este modelo, en el que cada proceso ocupa sus 5-10 megas, que no el que utiliza IE7 (por ejemplo) que no es nada difícil ver que se te pone en 120 o 150 MB de RAM. Que como vayas pelín justo (150 más del SQL Server Management Studio, otros 150 o 200 del Visual Studio, otros tantos de una de las instancias de 'svchost.exe' que vete a saber qué hace) te va a dar dentera de lo que se pone a 'rascar' el disco.
Ayy muchachos, se rompen el lado técnico de las cosas, es obvio marketing. No se uds. pero tienen que ver el fondo del asunto, la pelea de los estándares y todo ese rollo, así mismo lo del producto en si que planea desplazar al IE, ¿cuál es su página de inicio?, saquen la cuenta y verán q de 100, 70 u 80 son google.com y no otra (llámese live.com). Entonces "nosotros confiamos en google, por ende en su navegador tambien, y por ello consideramos mejor eso". Posicionamiento y Estrategia
No sólo de código y bits se vive.
Estimado Rodrigo hasta la fecha y con el process explorer abierto y con varios tabs abiertos iexplore.exe está solo en el árbol de procesos de mi maquina, y por muchos tabs que abra, navegue por webs sigue siendo un mismo proceso en el que sube la memoria, baja, se crean threads y se cierran. Pruébalo tú mismo teniendo el process explorer abierto mientras navegas con el IE y si en algún momento vez que iexplore.exe abre internamente otro iexplore.exe (además de modo InPrivate) me avisas :)
Yo lo que quería referirme con el chrome es que este nivel de aislamiento que han anunciado a bombo y platillo es la manera más fácil de hacerlo, claro que IE tiene aislamiento pero está implementado de otra manera mucho más granular. Y si alguien sabe lo más mínimo sobre cómo funciona Windows sabrá que el coste que tiene crear un proceso es grandísimo y un thread igual como para que google los ande desperdiciando a este nivel. Para que os hagáis una idea, Windows para crear un thread “gasta” aproximadamente 1 mega de memoria para reservar la pila, el stack y los registros del procesador, esto es el valor mínimo. Abre el process explorer y mira cuanto Threads tienes abiertos ahora, y multiplica, yo en el momento de escribir esto tengo 822 * 1 = 822 megas, ahí es nada. Mi única queja es que si lo mejor que ha sabido parir google con un sistema súper novedoso de aislamiento de tabs es esto, google deja mucho que desear, y como ejemplo he puesto el concepto que Microsoft puso en el Framework, AppDomain, que es un implementación más novedosa, y si alguien piensa lo contrario por favor que lo diga y exprese su argumentos pero razonando.
Saludos.
pues yo no me quejo del funcionamiento del chrome abre las páginas mucho más rápido que el ie y es un poco más veloz que el firefox. aun le faltan algunas actualizaciones que mejorarán su rendimiento pero yo ya uso más el chrome que el mozilla. la versión 3 del mozilla fue algo decepcionante para mi, porque algunas aplicaciones dejaron de funcionar. Por lo demás, está claro que google se lo ha currado en la campaña de publicidad, desde cuando un nuevo navegador sale en todos los telediarios?. de todas formas es curioso que google siga financiando a mozilla asta el 2011 y me da que google pone cara buena para acabar tomando el control de internet, de la informática y del mundo de la información. Que google anunciara a bombo y platillo su navegador es para robar usuarios a ie más que a mozilla, que en mi opinion este navegador irá degenerando hasta que los usuarios se pasen para el chrome.
Personalmente que lo de abrir un proceso por cada objeto de una web, no es por pestaña. Es decir, codigo html proceso, java proceso, flash proceso. (multi thread) Es realmente mejor y NO es mas facil. Ya que programarlo e integrarlo es mas dificil. Hace posible que se cargen webs sin esperar a ningun elemento, por lo que si por alguna razon uno es lento o no se carga porque este corrompida la web. Esta no se quedara bloqueada sino que funcionara perfectamente, con ausencia del que da problemas. Tambien hay que reseñar que otros sistemas operativos, por ejemplo los de la familia UNIX (son de los unicos que puedo ver el fuente). Tienen mucha versatilidad al usar multi-thread. Si windows necesita 16 punteros indirectos para crear un proceso no es culpa de google sino de microsoft (Creo que lo de los 16 punteros indirectos es realmente real). En Unix es una llamada al proceso INIT y de hay hace algo un poco largo y que no viene al cuento. Con esto no quiero debatir entre sistemas operativos, solo que hay varios y no se puede ver lo que es mejor para uno. Ademas, vista no deberia tener problemas para mantener varios procesos.
Es cierto que cada proceso necesita su espacio de memoria, que deberia ser el tema de debate en cuestion. Aun no he usado Chrome, ya que no esta para mi SO, pero eso es cuestion de hacer graficas, que seguro pronto saldran. Hay que tener en cuenta que la memoria es un recurso muy barato y que la gente llega a tener por regla general mas de 1 o 2 Gigas para juegos como minimo últimamente. Y el navegador esta en fase beta, que es posible que la estable salga el año que viene. Que seria el año en que empezaria que mirarse si los requisitos son exagerados o no. Pero si la gente que lo usa no trabaja mas lento el ordenador es que no hay problemas de memoria. Ademas han explicado que habian trabajado seriamente en la liberación de memoria, no dejando huecos libres reservados al matar procesos.
Ahora no tengo en mente mas cosas por las que pueda ser malo la creación de multiples procesos. Ya que decir que es malo, porque a un sistema operativo no sabe controlarlos, es cosa del SO. El tiempo nos dara la razon a ti o a mi. Pero como es una herramienta de codigo abierto, nos la dara cuando en 2 años o antes. Todos los navegadores usen multi-thread o alguien haya modificado esa parte del navegador y nos bajemos como locos todos esa modificación del Chrome.
Y menos preciar a los ingenieros de google creo que no viene a cuento. Ya que para entrar allí no hay que acabar primaria precisamente, que si estas en una empresa grande americana (ya sea microsoft, google, apple...) es que vales.
Pues siguiendo un poco con el tema, yo lo unico que estoy diciendo es que este navegador de google no tiene nada de innovador. Vayamos por partes. Google coge el WebKit de Apple y le pone una ventana y un skin y ahora se “inventa” el aislamiento de tab a nivel de proceso, lo empaqueta lo pone en su web y dice que ha salido un nuevo navegado. Seamos serios, Iceweasel ya cogió el código fuente del FF y ha sacado un navegado, hay decenas de sucedáneos de FF en base a él. Google ha hecho lo mismo con webkit, porque no veo que haya hecho desde cero un motor de renderizado de html. Acepto que google se lo ha currado haciendo el motor de javascript nuevo. ¿Por lo demás?, pues tu porque sabes que un proceso está aislado de otro?, en Windows 98 no era así y si un proceso se corrompía el sistema se caída. Pues es así porque Microsoft implemento el aislamiento de los procesos dentro del sistema. Eso fue una innovación. Ahora google coge ese aislamiento que proporciona el proceso y lo usa para su beneficio al decir que él asila las web, no. La integración de los procesos se ha hecho con pipes, a poco que abras el proceso con process explorer verás los nobres de los pipes en los argumentos de la línea de comandos y los manejadores creado. Y te digo que esto integrarlo no es difícil porque Windows tiene una función de Win32 que te permite abrir un pipe como si fuera un fichero y así pasar información, así de sencillo. Así que no te creas que google se lo ha currado tanto, como para atreverse a decir que Google Chrome es el futuro de los navegadores y es un S.O. online, la crisis de Windows, el azote de Microsoft. Y porque si esto es así el código fuente de Chrome tiene un fichero .sln de solución de Visual Studio, que hubiera programado el navegador en un intérprete de javascript y se lo programen con el vi en consola y no con Visual Studio 2005. Todo el mundo raja de Microsoft pero bien que todo el mundo usa Windows y Visual Studio para los proyectos de verdad. Desde mi punto de vista no ha hecho nada más que agitar las aguas con un software basado en Software Libre que le ha puesto el logo de Google. Nada más.
Voy a responderte a un par de cosas que creo que no son del todo exactas, pero sin malos royos.
[Google coge el WebKit de Apple...]
Teniendo en cuenta que es una herramienta open source, esa practica es totalmente licita, lo reconocen totalmente, ya que en ningun momento lo han negado. Como sera licito coger cualquier parte de chrome. Tambien tiene mas cosas innovadoras aparte de V8. Las sandboxes, es algo a destacar en la seguridad, por ejemplo.
[en Windows 98 no era así y si un proceso se corrompía el sistema se caída. Pues es así porque Microsoft implemento el aislamiento de los procesos dentro del sistema. Eso fue una innovación.]
Si y no... Es una innovación en el mundo windows, pero no una innovación en el mundo de los SO, ya que otros ya utilizaban ese procedimiento.
[Chrome es el futuro de los navegadores y es un S.O. online, la crisis de Windows, el azote de Microsoft. Y porque si esto es así el código fuente de Chrome tiene un fichero .sln de solución de Visual Studio, que hubiera programado el navegador en un intérprete de javascript y se lo programen con el vi en consola y no con Visual Studio 2005. Todo el mundo raja de Microsoft pero bien que todo el mundo usa Windows y Visual Studio para los proyectos de verdad.]
Aqui varias cosas.
Que utilizen Visual Studio para la version de windows de chrome es logico. ya que es un framework bueno, por que entre otras cosas el compilador de forma natural mas util para compilar en windows es el que hace microsoft que tienen todas las expecificaciones de su SO.
Pero ten en cuenta que ese framework es totalmente inutil para trabajar en la versión de MAC y la de Linux, por lo que en esas versiones utilizaran una framework par mac y otro para linux a la altura de cada uno de los otros, Y no veras archivos .sln en mac o linux.
Tambien es posible que utilizen un framework propio que para hacer el programa utilize un compilador o otro dependiendo del SO al que este destinado.
Y comparar VI con Visual Studio 2005, es sencillamente comparar un editor del año 1976 (MS-DOS aparecio en 1981) con un framework del 2005. No tiene sentido.
[...atreverse a decir que Google Chrome es el futuro de los navegadores y es un S.O. online]
Obviamente eso es publicidad que se dan ellos, pero vamos, que cada empresa cuando habla de su producto se le llena la boca, a google y a todas y en cualquier ambito, no solo en informatica. Hay si te doy la razon. Ninguno peca de humilde y dice. "y el futuro dira si hemos hecho un producto bueno o insignificante para la informatica." y ya.
Ciao
No veo ninguna utilidad al resourceDictionary. Al menos, tal como lo has implementado en el archivo.zip.
Si quitas el archivo ResourceDictionnary y las líneas del App.xaml, sigue funcionando igual.
Saludos y felicidades por el curso
Realmente no existe ningun curso, bueno, es una sucesión de post que estoy escribiendo para intentar solucionar los problemas que se encuentra la gente que viene de Windows Forms o quiere aprender WPF, así que si teneis alguna pregunta, sugerencia o lo que sea.
Saludos. Luis.
Crack,
Aquí te estaremos esperando.
JC's
¿Grabareis el evento?
Cantabria estal algo alejadillo de "La Mancha"
Gracias crack,
Si podéis, publicar también las ppts de la parte que dió Pablo.
Un saludo
Una sesión genial tio! Tenemos que repetir! ;)
JC: Esta noche estará mi parte en mi blog :)
Gracias chavales,
Pongo tb aquí el enlace al post de Pablo:
geeks.ms/.../back-to-the-bullet-sesi-243-n-de-depuraci-243-n-y-optimizaci-243-n.aspx
Excelente post ... por fin alguien se anima a escribir sobre Robotics Studio :D, seguiré con interés estos posts
Muchas gracias !!
Hola.
Sigo tu blog y te quería hacer una pregunta no relacionada con su contenido.
¿cómo lo haces para poner las cajas en donde introduces el código?
Es que en mi blog de .NET no consigo poner el código en condiciones y me gusta tu sistema.
¿Me puedes echar una mano?
Estimado Bendem, utilizo Windows Live Writer para escribir los post, y hay un plug-in para live writer que permite formatear codigo de esta manera. Que sepas que casi todos los proveedores de blogs soportan live writer. El plug-in se llama, Insert Code Snippet.
llevo tiempo pensando en comprarme un lego mindstorm!
Creo que al final voy a realizar la inversion
Saludos!
Hay algunas cosas que no entiendo Luis... quizás puedas aportar un poco de luz...
Robotics Studio es gratis. Y con Robotics Studio ya tienes acceso a CCR y DDS. ¿Por qué alguien querría pagar por esos componentes que son publicamente accesibles?...
Otra cosa que no se como estos componentes casan en una arquitectura y en que aspectos son complementarios o 'competencia' de Parallel Extensions...
¡Un saludo!
Bueno eso de Robotics studio es gratis no es del todo cierto!!. Se supone que Microsoft para estudiantes y entusiastas de la robótica pone Robotics Studio de manera gratuita, pero para profesionales o aplicaciones comerciales, recordar que Robotics Studio no es ningún juguetito, tiene un coste de $399. msdn.microsoft.com/.../bb521232.aspx. Así que aunque te puedas bajar la versión 2008 de Robotics studio y separar técnicamente CCR y DSS estarías violando la licencia.
En cuanto al uso de la arquitectura, por un lado tienes CCR que es muy parecido Parrallel Extensions, de hecho tenemos casi los mismo componentes Port, Dispatcher, DispatcherQueues y Task pero hay que recordad que Parrallel Extension está en beta y esto ya es una RTM. Su uso podríamos decir que está recomendado cuando no quieres o puedes usar WCF y necesitas procesar muchos mensajes en una arquitectura muy distribuida.
Si tienes dudas te invito a que leas los tres artículos anteriores que explican todos estos conceptos y dónde se pueden encajar en una aplicación.
"Necesitas procesar muchos mensajes en una arquitectura muy distribuida"... ¿suena a MSMQ?
"Cuando no quieres o puedes usar WCF" no se me ocurre ningún escenario...
¡Gracias por aclarar mi ignorancia sobre la licencia!
Buenas
Luis tiene razón, ahora hay que pagar; pero creo que la gran diferencia está en que hay que pagar por las licencias de distribución de applicaciones, no por las de desarrollo (según lo ultimo que recuerdo de MRDS); es por eso que Robotics Studio incluye las licencias, pero si quieres utilizarlo y desplegarlo, a desembolsar unos €€€ ...
Como bien dice la licencia: "MRDS es gratis para usos no comerciales ..." lo demás ya se lo pueden imaginar.
Bruno
Genial Luis!! Este tipo de artículos son los que me hacen interesarme por WPF y que, en el fondo, muy en el fondo, pueda llegar a admitir que WPF es algo mas que pintar colorines! Me encantan tus posts sobre WPF tio! :)
Qué ventaja ofrece derivar de DependencyObject tus entidades de negocio respecto a implementar INotifyPropertyChanged ?
Para ser el origen de DataBinding es suficiente y debería ser menos pesado y más natural ( y menos restrictivo en cuanto a la clase padre ).
Eres un genio, muchas gracias
Es cierto eso que comentas Pablo Alarcon, solo que la diferencia es que las propiedades son más ricas en cuanto a metadatos, tiene implementado las notificaciones porque son DependencyPropertys.
El uso que yo doy a las entidades de negocio en cliente para WPF es hacerles un Binding a la UI de WPF y usar DP me permite por ejemplo, establecer un Flag en los Metadatos de la DP que indique que esa propiedad afecta al Renderizado de mi control, cosa que sin DP no puedo hacer. Se podría decir que es cosa de gustos, porque estas notificaciones automáticas de que un control se tiene que repintar lo puedo conseguir yo mismo implementando esa funcionalidad, pero WPF ya tiene un mecanismo para hacerlo por mí y seguro mejor de lo que lo pueda hacer yo. Yo intento usar casi la mayoría de funcionalidad que viene en WPF antes de implementar cualquier cosa por mí, de hecho por ejemplo estoy en contra de cualquier modelo MVC MPM MPV o MVx que se pueda implementar en WPF, porque WPF tiene muchos mecanismos para implementar esta funcionalidad de la misma manera o de una manera más natural, solo hay que encontrarlo.
Es online?
Esta genial chicos, tengo ya ganas de probarlo en vivo.
Que bueno !!! no nos animamos a have run videito ???
Asi lo vemos en accion :D
Me parece extraordinario que gente como tu se ayude a muchas personas....Mi enhorabuena Luis
Muchas gracias Lenchu, si tienes algún tema especifico sobre el que quieras que escribas, aqui estoy.
Interesante approach, lo apunto para momentos de ocio.
Igualmente te cuento que yo fuerzo BSOD constantemente en mi ordenador utilizando, technet.microsoft.com/.../bb897558.aspx :D
Luis, interesantísima la entrada. Pero tengo una duda. Dices que le pasas la dirección de uno de los objetos DataRow al comando !GCRoot, pero no veo de donde sacas esas dirección. ¿Podrías aclararlo?
¡Gracias!
Pues la gente de Sysinternals tiene un programa que se llama NotMyFault que permite cargar un driver mal diseñado en el sistema y forzar BSOD a través de malas prácticas de programación de drivers, simplemente es para aprender, pero también funciona para forzar pantallazos azules.
He puesto una actualización del post explicando eso, porque se me olvido.
"Igualmente te cuento que yo fuerzo BSOD constantemente en mi ordenador"
Yo también, tengo una tarea programada que lo hace cada minuto y así no puedo trabajar y ya tengo excusa...
¿Tu lo haces también por eso a que sí?
XD
Bueno lo que comenta El Bruno es un salvapantallas, xD
Es una excusa muy buena.
Excelente, tio. ¡Como siempre! :)
Luis eres un crack
@2 Hey Luis gracias por aclararlo :D, el 2do comentario es genial.
@Andrechi, como que no lo puedes descargar? está en site de Microsoft y es un salvapantallas, es decir un archivo .scr; descargatelo en casa y pruebalo
enfermo mental
Super elemental! me hubiese gustado estar alla!
Ojala pudiera pasarme por ahi titán... :( ¡Aunque si te soy sincero, preferiria estar ahora mismo donde tu estas! ¡***! XD
Un abrazote tio!
a rechimba hay si puedo fastidiar gente con eso
Hola Luis:
Me voy a permitir lanzarte la petición de que, si es posible, escribas un pequeño artículillo sobre como desarrollar el 'hola mundo' para Surface. Un artículo que nos permita saber que pasos inciales debemos dar y que herramientas y SDKs necesitamos.
jejeje que envidia tio !!! pero me sumo a Ramon en la peticion y en especial al apartado donde para simular varios "touch" podemos pinchar varios ratones en el simulador de Surface, te partirias si vieras lo que cuesta organizar 5 manos diferentes para que simules 5 dedos :P
Joer que emoción!!!!!
Esto empieza a estar interesanteeeeeee!!!!, ¿habeis visto el video del 2019 de Microsoft? Es una pasada
Pues acepto el reto, prepararé un post sobre el "Hola Mundo Surface" con el ScatterView y con todas las cosillas del SDK.
Gracias. Luis.
Impresionante como siempre Maestro, jejejejeje.
Un abrazo desde Madrid
Muy bueno.
Que caña de caracterísica. La clase que has puesto me va a venir muy bien, tengo alguna solución que hace uso muy intensivo de timers. Eso sí, tendré que abstraer el que maneje la situación de no estar en Windows 7, supongo que no será muy complicado que la clase pase a usar timers 'normales' si estamos en Vista o XP.
Además supongo que con el tiempo acabarán abstrayendo este tema en la propias clases de timers del Framework.
Por último, he estado jugueteando con tu clase y he tenido que añadir algunas declaraciones en la clase UnsafeNativeMethods que me da que te has comido al pegar en el blog. Las he sacado del SDK y creo que sean correctas, por si alguien las necesita, aunque no las he provado a fondo:
public const int POWER_REQUEST_CONTEXT_VERSION = 0;
public const int POWER_REQUEST_CONTEXT_SIMPLE_STRING = 0x1;
public const int POWER_REQUEST_CONTEXT_DETAILED_STRING = 0x2;
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr handle);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct POWER_REQUEST_CONTEXT
{
public UInt32 Version;
public UInt32 Flags;
[MarshalAs(UnmanagedType.LPWStr)]
public string SimpleReasonString;
}
[StructLayout(LayoutKind.Sequential)]
public struct PowerRequestContextDetailedInformation
public IntPtr LocalizedReasonModule;
public UInt32 LocalizedReasonId;
public UInt32 ReasonStringCount;
public string[] ReasonStrings;
public struct POWER_REQUEST_CONTEXT_DETAILED
public PowerRequestContextDetailedInformation DetailedInformation;
¡Un saludo titán!
Por cierto, para que la clase se comporte correctamente en Vista o XP, supongo que el camino sería controlar la excepción EntryNotFoundException y para a usar un timer normal en lugar de estas nuevas API.
¿Se te ocurre algo mejor?... Seguro que después de unas pintas algo se te ocurre jejejeje...
¡Un abrazo!
Es cierto Rodrigo !!, es lo que tiene copiar y pegar.
En principio esa clase es para que funcione en Windows 7 directamente, supongo que tendrás que utilizar un Shims o tendrás que chequear la versión de Windows, aunque esto último no es lo más recomendable.
Donde he visto esto antes... ahh creo Mac OS X, pero muy antes :-) bueno en fin, buen post ;)
Mac ? ese quien es .. suena a algun amigo de alguien :P jejeje
no, en verdad parece una cosa simple pero como dice Luis, se pueden hacer muchas cosas, en code.msdn.microsoft.com/Windows7Taskbar hay varios ejemplos y links interesantes para meterse más de lleno :D
Muy bueno comentario realmente creo que tenemos que nos actualizar pues el futuro de las WPF yá estan en la puerta, como comentaste, la tecnologia xaml no tiene nada que ver con la antigua manera de trabajar y realmente toda la ayuda que nos podamos brindar siempre nos ayudará a avanzar mas rapido, gracias por tu aporte...
Hola Luis
Me has dejado con una inquietud. Nuestras aplicaciones la mayoría de ellas siguen siendo VB6, eso si, con codigo .NET incrsutado a base de Interops ¿Sabes si a través de interops podríamos hacer que nuestras aplicaciones sigan el comprtamiento marcado en Windows 7?
Hola Julio Trujillo, por supuesto que sí, de hecho toda la funcionalidad nueva de Windows 7 está solo en API nativa y no administrada solo que Microsoft ha sacado mucha documentación de como hacerlo desde .net
Aquí os pego el enlace, code.msdn.microsoft.com/VistaBridge
descargar milcore.dll para que no salga error del roxio creator 2009
Excelente artículo Luis.
Por lo que se, algo como esto:
static readonly Singleton instance = new Singleton();
el framework nos garantiza que es thread safe.
Javier, tu argumento solamente es cierto si la clase tiene un constructor estático, sino NO tiene porque ser cierta! Al no tener un constructor estático esa clase está marcada con 'beforefieldinit' y por lo tanto lo que dices no tiene porque cumplirse..
Para más info
www.yoda.arachsys.com/.../beforefieldinit.html
P.D: Buen post Luis!!
Unai
Aupa Luis!!!
Sé que si tu y Unai estáis de acuerdo, algo se me tiene que estar escapando...
Pero no entiendo para qué es necesario implementar el patrón singleton como tu sugieres. ¿Qué tiene de malo la implementación que pongo a continuación? Yo creo que la inicialización es 'lazy', pues no se ejecuta hasta que llamamos a Instance y además es 'thread safe' pues los constructores estáticos lo son.
¿Qué se me escapa?
Aquí va la implementación que yo haría:
class Singleton
private Singleton() { }
static Singleton _instance;
static Singleton()
_instance = new Singleton();
public static Singleton Instance
get { return _instance; }
Rodrigo, yo solamente he echo un comentario respecto al tema del comentario de Javier, para que sea ThreadSafe la clase tiene que tener un constructor estático ( eliminar BeforeFieldInit como decorador) como haces tu.
Referencia de MSDN
"TypeAttributes.BeforefieldInit
Specifies that calling static methods of the type does not force the system to initialize the type"
Rodrigo lo que dices es cierto, este Singleton es ThreadSafe, pero solo porque tiene el constructor estático, ya que el framework se asegura que el constructor estático es llamado solamente una vez, utilizando el double-lock. Pero para el ejemplo de Javier, ese campo tiene marcado el BeforefieldInit que básicamente lo que viene a decir es, que no fuerce al sistema a inicializar este campo cuando se construye el tipo (constructor estático), lo que puede hacer que no sea ThreadSafe.
Si se marca con el attributo que comenta Unai, entonces sí, porque este campo se inicializaría con el constructor estático.
Puede que el título del artículo no sea muy claro, pero lo que pretendía explicar son las posibles diferentes implementaciones del Singleton perezoso, es decir que no se inicializa el valor con el tipo sino que se construye después.
Se me olvido ponerlo antes. Muy bueno el post y los comentarios que se han abierto.
Es curioso, no lo conocía, he usado las propiedades de dependencia solo en un par de ocasiones y por que el API con el que trabajaba las usaba, de todas formas no logro entender como apesar de hacer cast (que es una operación que lleva más tiempo), es más rápido. Tengo que ver el IL.
Un saludo,
Carlos.
Hola,
Buenisimo el tutorial!
Probare si funciona en mi pobre XP.
Gracias.
Perdona Luis, pero en la implementación de ejemplo de 'ConcurrentDictionary.TryGetValue' ¿no debería usarse 'AcquireReaderLock' en vez de AcquireWriterLock'?
Gracias tio! Eres un crack!
Nos va a venir de perlas para tratar de provocar el caos y la destruccion en las aplicaciones que sufran potenciales problemas de rendimento y escalabilidad.. las dejas tontas con esta herramienta y zassss... WinDbg... y luego liberas presion y zaaasss.. otra vez WinDbg... yiiha! xD
Gracias tio!!
Concuerdo contigo completamente en cuanto a que JS y HTML, para hacer algo mas o menos bueno, son puros hacks =/ pero bueno depues de todo la web no esta tan mal
No os preocupéis... algún día llegaréis a cogerle el gusto.
Hola!
Hombre... hoy en dia usar javascript "a pelo" para hacer algo en tu página web no sólo es tedioso y propenso a errores: es tirar el tiempo.
Hay librerías especializadas como jQuery/jQueryUI y Prototype/Scriptaculous (por citar las dos más conocidas) que llevan el desarrollo javascript a otra dimensión.
Javascript como lenguaje no está tan mal como mucha gente cree... lo que pasa es que la gran mayoría se quedó en el Javascript de hace años, antes de la aparición de la palabra clave "prototype" ;-)
Hola Eduardo,
Como bien comentas hay muchas librerías para programar en javascript, pero aun así seguimos sin tener un compilador, seguridad de tipos y una serie de ventajas para la programación, además de que estamos trabajando con un lenguaje que tiene muchos años hay que renovarlo.
Yo me refería más la combinación mortal de Html + Javascript + Estandares + 1001 navegadores que hace lo que quieren. Yo prefiero SL o Flash porque solo hay una versión, así no te tiene que complicar la vida.
Hola Luis ;-)
En lo que sin duda tienes razón es en lo de "estandares + 1001 navegadores que hacen lo que quieren". Es la cruz de la web... :p
Ahí si que no hay nada que añadir, y diseñar una web que se vea bien (ya no digo igual) en todos los navegadores es una tarea a veces titánica...
Sobre la renovación de javascript se ha hablado largo y tendido. Javascript ha evolucionado MUCHO a lo largo del tiempo y del juguete que era en su versión 1.0 ha pasado a ser un completo lenguaje en su versión 1.8. Pero insisto, hay realmente POCA gente que domine javascript en todo su potencial (y no, no me incluyo entre ellos desafortunadamente).
Compiladores en javascript ya hay: el V8 de Chrome funciona como un JIT para javascript y creo que FF 4 va a incorporar algo parecido (o era 3.5???).
Referente a la seguridad de tipos, efectivamente javascript se diseñó para no tener tipos estáticos, lo que puede ser una ventaja o un inconveniente según se mire.
Nota que en el comentario simplemente me refiero a javascript, en lo de hacks de html+css y todo esto ya digo que estoy de acuerdo contigo!
Un abrazo!!!
Hola Luis, gracias por el ejemplo y tus cometarios en mi blog.
Aunque el código que puse allí si que funciona y es correcto... solo que por alguna razón meti el codigo sin fijarme que la declaración de volatile me quedo por fuera del bloque formateado ;)
De todas maneras tu blog esta muy interesante acerca de Singleton, ese iba a ser mi próximo articulo y realmente yo no llegaba sino hasta el sistema de doble bloqueo. Me gusto mucho la implementación que haces con Interlocked.CompareExchange, espero que no te moleste si hago referencia a eso mismo en mi artículo.
saludos.
Excelente artículo Luis!
Muy bueno. Saludos.
Es un tema interesante, sin embargo erras cuando haces mención de los threads y sus problemas subsecuentes de sincronización. Los Task, que es en donde se apoyan las instrucciones en Parrallel no son realmente threads por cuanto no hay temas de sincronización asociados. Un thread es interrumpido para permitir la ejeción de otro thread dentro del mismo proceso, mientras que los task se ejecutan independientemente sin sincronizar entre si , cada uno como si fuera un proceso independiente dependiendo unincamente de la calendarizacion del sistema operativo. Esa es una de sus mayores ventajas, que al no tener tareas sincronizacion ni cambios de contexto dentro del propio proceso, hacen la ejecución mucho más eficiente.
Estimado Juan Carlos, me gustaría puntualizar tu comentario porque me parece que no he entendido lo que quieres explicar, según tú las Task no son realmente threads y no tienen temas de sincronización asociadas. Bueno eso es cierto a medias, porque como comento en mi siguiente artículo, los Task se pueden ejecutar de manera síncrona y asíncrona lo que quiere decir que se puede utilizar el TaskScheduler predeterminado, el del ThreadPool que implica el uso de Threads para su ejecución, así que esto no es cierto siempre.
A partir de este punto estoy muy confuso porque me parece que no has entendido que son realmente las Task. No son ningún objeto nuevo del SO operativo, para que se “ejecuten independientemente dependiendo únicamente de la calendarización del sistema operativo”, a que te refieres con eso que el SO tiene otra unidad mínima de ejecución que no son los Threads?, desde cuando el kernel de Windows puede ejecutar Task como tales?, de hecho ni siquiera .NET tiene noción de lo que son los Task, simplemente ejecuta código en un thread. Lo único que los Task una manera muy sencilla de abstraer esa complejidad necesaria para paralelizar la ejecución de todo ese código. Así que no veo porque las Task tiene una ventana que no tienen cambios de contexto cuando son cosas que están en diferentes niveles de concepto, un cambio de contexto se realiza cuando un thread agota el cuantum de tiempo o espera por algún evento externo haciendo que Windows guarde el estado de la pila y los registros en el objeto contexto asociado al TEB del thread que es completamente nativo.
Te invito a que te leas el siguiente artículo de la TPL de mi blog y que veas este video para que entiendas un poco mejor con funciona por dentro.
channel9.msdn.com/.../TL26
Excelente Luis, espero impaciente las siguientes entregas.
Muchas gracias Juan, se agracede.
Hola Luis, desde luego no hablo de Task como otra unidad de ejecución, pues desde luego por debajo todos son threads del sistema operativo , el punto es que tu puedes abrir un task y este hara uso de un Taskpool que es parecido al threadpool pero no es lo mismo, el taskpool controla que tareas se ejecutan en cual procesador y solo una vez la tarea termine su ejecucion este utilizara ese procesador 'libre' para enviar la siguiente tarea en espera a ejecucion.
Un Thread es libre de ejecutarse en diferentes procesadores segun la calendarizacion que el sistema operativo haga para el proceso en donde corre el thread. En tanto un Task no sera calendarizado para usar sino un solo procesador hasta que este acabe.
Segun recuerdo, un Task no cambia al estado suspend y luego a resume como sucede con un Thread cada vez que es asignado tiempo de ejecucion a otro hilo de un mismo proceso. En un Task eso no existe, porque el Task no entra en competencia con la aplicacion actual por el tiempo procesador, ya que de hecho el task y el hilo principal dela aplicación se ejecutan en procesadores diferentes de manera simultanea.
Recuerda que mientras un hilo es solo un truco para simular paralelismo a traves de hebras que intercambian tiempo de ejecución. El Task realmente SI se esta ejecutando de manera paralela en un procesador diferente, lo cual le evita pasar por los cambios de contexto para que se ejecute el hilo principal de la aplicación.
En el video que me pasas incluso puedes apreciar como el mismo algoritmo implemantado haciendo uso de Threads y luego haciendo uso de Task se ejecuta muchisimas veces mas rapido gracias al impresionante ahorro de tiempo al evitar los cambios de contexto durante la ejecución.
Un Task, si bien en un nivel mas bajo es un hilo, no es realmente un Thread desde el punto de vista del CLR, ya que estan hechos para propositos diferentes.
En verdad vi ese video hace ya como 6 meses y puede que est confundido, asi que lo revisare, pero creo que deberias pegarle una revisada tambien.
“Un Thread es libre de ejecutarse en diferentes procesadores segun la calendarizacion que el sistema operativo haga para el proceso en donde corre el thread. En tanto un Task no sera calendarizado para usar sino un solo procesador hasta que este acabe.”
Tengo que decirte que en la primera parte llevas razón, eso se llama Thread Affinity. Pero con respecto al segundo punto, estamos hablando del mismo concepto, que diferencia a un thread de un Task?, pues conceptualmente nada, porque los dos intentan ejecutar una función, un delegado en un thread diferente, el caso es que Task utiliza el ThreadPool de Windows que esta optimizado para reutilizar threads pero en esencia es lo mismo, los dos son thread un creado a mano y el otro creado de una manera más sofisticada. Es lo que explico en mi segundo artículo de TPL.
“Segun recuerdo, un Task no cambia al estado suspend y luego a resume como sucede con un Thread cada vez que es asignado tiempo de ejecucion a otro hilo de un mismo proceso. En un Task eso no existe, porque el Task no entra en competencia con la aplicacion actual por el tiempo procesador, ya que de hecho el task y el hilo principal dela aplicación se ejecutan en procesadores diferentes de manera simultanea.”
Cuando he dicho yo que un Task cambia a estado Suspended y luego se resume, al ser código normal, puedes seguir usando tus primitivas de sincronización como lock, (Auto/Manual)ResetEvent, Interlocked, Semaphore, ect. ¿Cómo que un Task no entra en competencia con la aplicación actual por el tiempo de procesador?, hasta lo que yo se aplicación es un contenedor lógico que asigna Windows a un conjunto de Threads, así que sí entra en competencia por supuesto porque un thread normal y un Task son lo mismo.
“Recuerda que mientras un hilo es solo un truco para simular paralelismo a traves de hebras que intercambian tiempo de ejecución. El Task realmente SI se esta ejecutando de manera paralela en un procesador diferente, lo cual le evita pasar por los cambios de contexto para que se ejecute el hilo principal de la aplicación.”
Un truco? pues vaya tela, y antes de los Task que se usaba? No había paralelismo?, y un pequeño detale Thread y Fiber (hilo y hebra) son dos conceptos diferentes. Los threads utilizan el scheduler del kernel mientras que las fibers utilizan un scheduler de usuario.
“En el video que me pasas incluso puedes apreciar como el mismo algoritmo implemantado haciendo uso de Threads y luego haciendo uso de Task se ejecuta muchisimas veces mas rapido gracias al impresionante ahorro de tiempo al evitar los cambios de contexto durante la ejecución.”
Esto es mezclar conceptos que son completamente diferentes, se ejecuta más rápido en comparación a qué? Y que tiene que ver los cambios de contexto para eso? Lo que ves en el video se llama Work-stealing y es un mecanismo para optimizar el uso de procesador, de hecho se le puede notificar el TaskScheduler que lo deshabilite con esta flag a la hora de crear una Task con TaskCreationOptions. PreferFairness.
“Un Task, si bien en un nivel mas bajo es un hilo, no es realmente un Thread desde el punto de vista del CLR, ya que estan hechos para propositos diferentes.”
Error, un Task es un nivel más alto, un thread es de bajo nivel el CLR (maquina que ejecuta el código de framework) no entiende de Task, entiende de thread. De hecho Task envuelve a Thread porque un Task contiene un Thread (semánticamente hablando).
Te pasteo de la web de TPL de Microsoft la definición de Task:
msdn.microsoft.com/.../dd460717(VS.100).aspx
In the TPL, the basic abstraction is the Task, not the thread. A task is an instance of the Task class. A task can be canceled and waited on, and can return a value, and can invoke another task when it completes. And when you use Parallel.For and Parallel.ForEach, even the Task object itself is implicit. In your code, you simply supply the delegate that performs the desired work. The TPL handles the rest. By default, the TPL uses its own task scheduler, which is integrated with the .NET ThreadPool. However, you can also provide a custom task scheduler that uses some other thread-scheduling mechanism. There is no fixed relationship between a task and a thread. A thread may run several tasks in succession for any given block of parallel code. A task may define a child task that runs on the same thread, or a different thread. A task may also invoke another task that has been defined elsewhere.
A mi para lo que me gusta el ContinueWith es para implementar el viejo patrón pipe, el que podemos paralelizar ciertas partes pero necesitamos el resultado total de esa paralelización para continuar con el siguiente paso del proceso.
Excelente serie de artículos.
Un saludo titán.
VALE Luis!
Segurtamente que tienes razon, como te he dicho vi ese video ya hace un tiempo y ni mas, asi que le pegare una repasada.
Gracias por tu paciencia!
No veo barra de Scroll o es que no entiendo la nueva experiencia de usuario?
Jajjajaj.... Pedro, anda que no lo he dicho veces... es que no estamos hechos para estas interfaces modernisimas... la barra es un paradigma obsoleto, acabado, no sirve, hay que innovar... tu mueve el ratón arrastrando el fondo y ya tienes scroll.
HOla¡¡ Luis buen articulo, perdona que te escriba este post aquí en el blog, pero me dijiste en la codecamp que te escribiera mi dirección de correo en el blog.
slcorral@gmail.com, mandame un mail cuando puedas ¡¡¡ Gracias¡¡¡¡.
Hola. Alguien sabe si hay una skin que permita modificar la taskbar en windows 2k?
Hola, segun veo es necesario escribir el helper para cada servicio, cosa que desanima inicialmente (a menos que hubiera una plantilla .tt o una custom tool que regenerara el helper).
Solo quería comentar que se puede declarar el eventhandler en modo inline, y a continuación la llamada asíncrona, es decir:
Cliente.GetTokenCompleted +=
(object sender, GetTokenCompletedEventArgs e) =>
var resultado = e.Result;
};
Cliente.GetTokenAsync();
Con lo que no sé si se justifica usar el helper por ahorrarse una línea, teniendo en cuenta que el helper agrega muchas más.
Hola pvila, como tu bien comentas, eso mismo lo podemos obtener de esa misma manera, pero el código que generamos no es tan limpio y organizado. Una de las cosas que quiero con este Helper es esconder el tener que subscribirse a los eventos y luego obtener los datos, además de que puedo tener un lugar centralizado de tratamiento de excepciones de invocación al servicio web.
Muchas gracias por el comentario. Luis.
<url>www.dontstayin.com/.../pamela-anderson-nude|Carmen Electra Nude</url>,
Luis puedes compartir el codigo de ejemplo?
saludos
Hola Paco!
Gracias por tu comentario, lamentablemente no puedo compartir ese código porque es parte de una aplicación que estamos desarrollando para Microsoft así que no es posible.
Hola Luis, te estuve escuchando en la charla que distes en deusto de TPL y Mef y la cuestión es que cacharreando con for.paralell llego a un outofmemoryexception, lo que quería saber es como asignar mas memoria al framework, y cual es el nombre de la herramienta que utilizabas para analizar el performance (nº de hilos, memoria usada....) en la presentación, gracias!.
Hola a todos! Dentro de poco empieza la gira de lanzamiento de Visual Studio 2010 por España y en este
Muy bien, gracias a este blog tuve oportunidad de involucrarme más en un tema tan apasionante como ese si hya oportunidad puede que me una a tu causa con alguna charla por estos lares.
saludos,
Muchas gracias Luís!
Así me gusta, con WCF RIA Services..
A la próxima me voy contigo para escucharte :-)
WCF Ria mola, pero me mola más hacerlo a mi :), además el material venia de corp directamente así que no tenia elección
Vale gracias por el video, ta bueno.
Estooo... no van los enlaces al case study... :(
PD: Y felicidades!
Pues he probado los enlaces y funcionan, a alguien más no le van?
Ahora van... te juro que esta mañana no me iban!! Me decía que el case study no existia...
En fin... :)
Felicitaciones che !!!
para cuándo un webcast de MEF ?? salu2grz
De verdad que leer tus artículos es uno de mis hobbies!
muy bueno.
Muchas gracias por tus comentarios Juan Carlos!
estuve ayer en tu charla de Surface en Microsoft, soy Miguel López de Albacete y te quería pedir aquella información que nos comentaste sobre cómo usar Visual Studio 2010 y Expression Blend 4 para programar WPF con Surface...
Gracias de antemano y un saludo,
Miguel
caramba, no me había enterado de esto. Fué online?
arrg, hay manera de descargar este fantástico vídeo?
Hola Jesús!
El curso lo organizo Microsoft España, el video lo puedes descargar, en el html está la url :) Un hacking simple.
Una cosilla algo relacionada con esta... en teoría desde el Guide debería poder accederse al nombre de usuario no? En la Beta todavía no lo he probado, pero en la CTP creo que había que estar registrado como desarrollador para poder hacerlo.
Mi enhorabuena para Rodrigo, pero sobretodo para Plain Concepts: habéis hecho un gran fichaje :-)
Vi el vídeo de un compañero tuyo: Mooooooola. Es como el flores vs zombies pero posicionas libremente a los "bateadores", con lo que da más libertad... para cagart@ en los put@os zombies de los cohones... :-)
Me gusta la lista de "cosas interesantes del juego". :-P
Felicitaciones! Ha comprarme un móvil con Phone 7 y luego a hacerme de ByeByeBrain...
¿Solo 2 meses, solo 3 personas?
PD: bonitos wallpapers, ¿podrías ponerlos a mas resoluciones para poder usarlo en mi laptop?
Muy bueno el punto de vista del tower defense, un gran aplauso :D
Hola Arturo!
Puedes descargarte unas versiones más grandes de mi blog en inglés luisguerrero.net/.../byebyebrain-tower-defence-game-from-plain-concepts.
Gracias a todos por los comentarios :)
interesante, gracias. Y algo de proxies WCF (en .net 3.5, y .net 4.0) para aplicaciones web asp.net ?? salu2grz
Brutal, enhorabuena Luis, estos son conceptos que deberían estar claros como el agua para cualquier programador de .net
Un abrazo titán!
Me alegra que te haya gustado :)
Muy bueno el artículo!
Me hizo gracia lo del GC tuneado XD
Buen artículo, si señor... curioso lo de 'pinear' objetos.
Sólo un apunte, en la tercera línea del tercer párrafo me ha hecho gracia lo de "La memoria no es finita"... supongo que te has dejado un -in- ;-)
Joder, por fin, un tio con sentido común... :)
xDDD eres un figura!
Ahora esperate que antes o después te enlazaráon como post de porque no usar pruebas unitarias x)
Más claro, agua
Esto hay que leer se lo sin respirar, para que tenga sentido.
Hay un punto de que se habla el articulo. La reescritura de las pruebas unitarias cuando se cambia la libreria que prueba. No esto un, un sintoma de que hay algo mal hecho. Las pruebas unitarias sirven para asegurarnos de lo que funciona, siga funcionando. Así que si se modifica una libreria para meter le más funcionalidad, la funcionalidad antigua deveria seguir funcionando. Así que la prueba unitaria antigua no se deberia de tocar.
además para que usar .net si puedes usar lisp
Si algun organismo como la NASA, la BMW o la BOEING dicidieran como Luis Guerrero, que todo lo que hacen siempre va estar bien y que no necesitar asegurar nada de calidad, depronto seriamos neardentales que no necesitariamos computadoras.
Tu problema es que no utilizas INTEGRACIÓN CONTINUA:
es.wikipedia.org/.../Integraci%C3%B3n_continua
No trabajas con un grupo de gente y con el código que picas te resulta suficiente. La gran utilidad de las pruebas unitarias es ejecutarlas cada 15-30 minutos sobre el código en el repositorio. Te ahorras infinidad de problemas cuando estás coordinando un grupo de trabajo.
Creo que hay gente que no ha pillado la Ironia XDD
Te ha faltado el
[Modo ironía = ON] Blabla [Modo ironía = OFF]
Hay quien no lo ha pillado
Churrasco, lo mejor es que el comentario de Ironia OFF esta en el post, solo hay que buscarlo :)
Ya esta corregido Lluis :) muchas gracias.
Lo de 'pinear' objetos es para un escenario muy avanzado de invocación de memoria nativa y marshalling pero está bien saberlo.
Leamos mejor el post de otra forma, todo lo que dice son el fundamento de porqué hacer PRUEBAS UNITARIAS. Jejejeje.
Francisco J.
Buaaaaaa, Luis Guerrero es un TECNICOLESS!!!
Ajajjaa, pruebas unitarias?
¿ Que es eso???
Completamente de acuerdo con tu post.
^^ Cool :
XDDD
Pillado L. Yo tampoco las hago.
Un saludo!
Lo importante en la construcción de software son las personas. Las herramientas importan,Las técnicas también importan,Los procesos importan,Pero por sobre todas estas cosas que importan están las personas.
Los grandes desarrolladores crean gran software no porque siguen las reglas de alguna metodología, sino porque son ingenieros verdaderamente capaces.
(I’m sorry this post is in Spanish, it’s related to a topic that has appeared recently in the Spanish
Qué buen tip!
Muy buena informacion... " y si tenéis algún problema no dudéis con contactar con el equipo DOT ..."; si, tengo un problema, pues una aplicacion hecha en vbnet express 2005 se pone lenta luego que la dejo de utilizar 10 o 20 minutos...
Que sera lo que sucedera...?, tengo 3 arraylist shared cargados desde el comienzo de la aplicacion para compartir colecciones de objetos durante la ejecucion, queriendo con esto evitar el acceso a la base de datos...
Gracias por lo que puedan aportar
Hola tavl, gracias por el comentario :). Asi directamente es bastante dificil saber dual es el origen del problema. Pero mira que no te dejes referencias a objetos en tu aplicación.
Excelente artículo Luis, lo dificil es conocer cuando debemos utilizarlas y cuando no, y que en un equipo de trabajo todos utilicen las mismas reglas, a veces abusamos de las excepciones, otras sin embargo no las utilizamos cuando deberiamos, espero impaciente el siguiente artículo.
Gran post.
La clave, para mi, es la frase "Es decir, ¿puedo implementar un método Load teniendo en cuenta que el fichero no existe?, en mi opinión creo que no, porque justamente ese es uno de los requisitos del método, leer el fichero y de serializarlo. Si el fichero no existe no podemos continuar."
Exactamente, la existencia del fichero es una precondición de tu método. Ni más, ni menos. Una llamada a tu método con un fichero inexistente incumple la precondición por lo que la llamada es inválida. Y como desarrolladores NO deberíamos jamás de "protegernos" ante llamadas inválidas.
@Juan Irigoyen gracias por tu comentario, muchas veces también es el sentido común el que tiene que decirte cuando usarlas o no, hay que pararse tiempo para pensar que estamos implementando y cómo se va a usar.
@Eduard justamente una precondición de mi método es que exista el fichero, pero también comento que no es necesario tratar esa excepción por que el propio método OpenFile ya se encarga de hacerlo y no tengo que volver a comprobar lo mismo. De hecho como en la clase tengo una propiedad Exist podría haber escrito código para comprobar que el fichero existe antes de hacer la llamada, pero he preferido que sea el propio clr el que lance la excepción por si solo y no yo.
@Luis
Correcto, estamos diciendo lo mismo :D Sólo era para enfatizar ;-)
Es cierto, puedes usar Exist para verificar que existe el fichero. Y si no existe qué?
Lanzas una excepción?
Devuelves null?
En el primer caso todo queda igual (excepción o excepción) y en el segundo caso volvemos al tema de los null que comentabas al principio.
Así que al final como dices... que fluyan las excepciones!
Esta es una de las cosas que más me generar un conflicto interno cada vez que desarrollo código, por que necesitas saber si vas a usar tú la clase o no, tener un gran conocimiento de la API del framework en sí misma, para poder determinar que el método OpenFile lanza una excepción (o por lo menos consultar la documentación).
También otra de las cosas por las que vale mucho dejar las excepciones fluir, es justamente por la búsqueda de errores. El mejor caso a la hora de buscar un error es que siguiendo una serie de pasos se lance una excepción y podamos capturarla y solucionarla. Pero si en vez de eso nos encontramos, con la típica salida de Visual Studio de: “FileNotFoundException on mscorlib.dll” ¿Qué solución le damos a eso?, ¿por dónde empezamos a buscar ese error? Hay que ser un virtuoso de WinDBG+SOS.
Excelente Luis! E
Estoy de acuerdo con la visión que ofreces, muy en la línea que comenta Eduard. En este caso la existencia del fichero lo vemos como una precondición del método Load, como una parte mas de su contrato => si no se cumple el contrato al realizar la llamada esta debe fallar. Muchas veces se tiende a tratar excepciones que no debemos/podemos tratar dentro de nuestros métodos.
Creo que, en general, se hace un uso "sobredimensionado" de las excepciones y las usamos para solucionar problemas que nada tiene que ver con las excepciones, por ejemplo para controlar el flujo del programa...
Hola Josep Maria!
Exacto, lo que comentas del uso indebido de las excepciones, es justamente la parte que quiero tratar en el siguiente post, hablar de no usar las excepciones para hacer validaciones y controlar el flujo de ejecución de tu software (salvo en contada ocasiones).
Gracias por el comentario. Luis.
Muy bueno el articulo y estoy de acuerdo en lo que dices. Pero a menudo me he encontrado en situaciones en la que justificar esto cuesta trabajo, por dos siguientes motivos.
1.- Hay muchos programadores que no entienden lo que es una excepción. Y no me refiero solo a como están implementadas internamente, si no que una excepción es algo excepcional. Y aunque suene ridículo, la gente le cuesta asumir la idea.
2.- Y otro problema en trabajar de esta forma, es que las librerías hay que depurarlas muy bien. Y eso es tiempo. Aunque así sea más fácil el depurarlas y el resultado final es bastante mejor, es difícil justificarlo.
Otro tema que hay que tener muy en cuenta es que a los usuarios no les interesan las excepciones. Con lo que las excepciones que no consigas capturar, escóndelas (al usuario, no a ti mismo) Así que mételas en un fichero o similares.
Sería interesante hacer un estudio del tiempo que se tarda en dejar fino una aplicación. Desde que supuestamente cumples todas las especificaciones, hasta que consigues que todos los posibles problemas que tenga la solución tengan un tratamiento elegante.
Hola Andrechi!
Como también dice Rodrigo Corral, “la calidad no es opcional”. Así que no tendrías que justificar el tener que hacer las cosas bien, sino que siempre las tendríamos que hacer bien. Lo que comentas en el punto 2, es que es más fácil pensar las cosas antes que intentar esconder el bulto haciendo un Try/Catch vacío, al final sale más caro.
Es cierto que a los usuarios no les interesa las excepciones, y debería de ser así. Yo lo único que estoy diciendo es que si estás haciendo una clase o API, para que otras personas la usen, que deberías de dejar fluir las excepciones para no aumentar la complejidad del componente, y ceder la responsabilidad al que usa tu clase. También digo que una excepción te muestra un síntoma de un error, y que la excepción en sí no es un problema, sino que representa una condición que no se debería de haber dado en tú código pero lo ha hecho. Por supuesto que tienes que tener esto en cuenta, pero hay maneras de hacer comprobaciones para no lanzar excepciones porque sí.
Fíjate, por ejemplo, el clásico ejemplo de conectarte a una base de datos SQL Server remota, y que la base de datos no está disponible. Donde haces el Try/Catch, ¿en la capa de acceso a datos? (por simplificar), o lo haces en la UI que consume ese servicio de datos. Según lo dicho hasta ahora no deberías de tener ningún Try/Catch en el código de la capa de acceso a datos, y si un Try/Catch cuando intentas hacer login por primera vez en la app, y si la Api de acceso a datos, lanza una excepción, entonces es el momento de que mires el tipo, el mensaje y muestres un mensaje amigable al usuario diciendo lo que ha pasado, pero nunca en la API de acceso a datos en sí.
Estas las habéis hecho vosotros? o son como la de Antena 3 televisión? que os apuntáis tantos que no son vuestros...
Un saludito
Si, si estas las hemos hecho nosotros. Y es cierto, yo en A3 me precipité por error y pense que era nuestra. En realidad solo les habíamos ayudado. Ya me disculpe publicamente por el error en el mismo medio en que lo cometí. Y borre el tweet erroneo.
Este tanto si es nuestro y para más ironía se me olvido decirlo, pero sí. De hecho tengo pendiente un post sobre cómo se hizo y cuáles son las técnicas que usamos en TFS y demás.
Yo tengo las aplicaciones instaladas, está muy bien Luis!
@preguntoncojonero, al menos podías haberte puesto otro nombre para no suplantar al auténtico :-)
@pregunterocojonero el usuario más odiado y querido :P
Muchas gracias por el articulo, es muy interesante.
Me ha impresionado la disciplina a la hora de utilizar Scrum y como la habeis aplicado a un desarrollo de WindowsPhone.
Ojala mi trabajo fuese asi ;(
En mi caso de momento me tengo que conformar con desarrollar cutreaplicaciones en mi tiempo libre para WindowsPhone7 y soñar con publicar alguna en marketplace...
Luis ... excelente post !!! buenas prácticas aplicadas por doquier, a seguir con el buen ejemplo :D
Salu2
interesante artículo, más empresas deberían trabajar así :)
Muy buen articulo Luis. Sólo tengo un par de preguntas:
- De acuerdo a tu diagrama de arquitectura general, tendrías una sola solución en el Visual Studio con todos los proyectos?
- Si tendrias todos los proyectos en una sola solución entonces cada vez que necesites generar una nueva rama para la empresa XXX, esta rama contendra todos los proyectos de tu diagrama de arquitectura?
Hola Victor!
Efectivamente, como el diagrama indica (sacado de Visual Studio) en mi solución tengo todos los proyectos de las tres aplicaciones, El Pais, As y Cinco Días. Esto es así porque como comenté al principio del artículo, el proyecto era de las tres aplicaciones a la vez por eso consideré oportuno tener en la misma solución las tres. Una vez que se hicieron las ramas, ya no tenía tanto sentido tener todos los proyectos juntos, pero bueno eso me permitía hacer un merge de una rama reléase, de por ejemplo El Pais, a la rama de Main sin cambiar el .sln.
Y sobre la segunda pregunta volvemos a lo mismo, el proyecto no se pensó para más aplicaciones sino para esas tres, con lo cual no voy a tener ese escenario de tener que generar más proyectos y más ramas. Lo suyo hubiera sido quitar los proyectos de As y Cinco Días de la solución de El Pais, pero como estábamos comodos con eso nos pareció bien, además el tener ramas nos permitía cambiar cosas del proyecto de PlainConcepts.Common en la rama de El Pais sin que esto afectase a la rama de As (por poner un ejemplo) y después hacer un merge de todo eso a Main y testear que ese cambio no ha impactado en el resto de aplicaciones. Una de las cosas buenas que tiene tener un ensablado común es que te ahorras código, pero tienes el problema de que cada cambio impacta más partes de otro software, y esto con las ramas lo minimizábamos.
Espero que te sirva, si tienes alguna duda más no dudes en contestar.
Más posts de builds de servidor, deploy, etc serían de agradecer. Muy bueno señor.
Qué significa "que la compilación en modo reléase, desplegar esa fichero generado por el servidor de compilación en el teléfono..."
teléfono ? mi casa ?
salu2grz
Hola preguntoncojonero!
Pues que si tenemos un servidor de build, la gente de testing puede obtener el binario recién compilado de ahí, sin tener que instalarse nada de desarrollador en sus máquinas. El tester no tiene que bajarse la solución de Visual Studio y compilarla en local. Además de que así si encuentra algún error puede asociarlo a una build especifica.
Muchas gracias por tu respuesta. Te hice esas preguntas porque yo tengo un caso parecido a tu post, con la única diferencia, a parte de ser aplicaciones web, es que en mi proyecto existe el caso que puedo tener un nuevo cliente con sus funcionalidades particulares (images, estilos, controles, etc.) por lo que me preocupaba el hecho de tener todos los proyectos en una solucion. Por lo tanto, había pensado tener una solución por cada cliente pero todas las soluciones tendrian añadido los proyectos comunes.
Básicamente, habia pensado en esta estructura:
> COMMON CORE (Bibliotecas de clases comunes)
---->MAIN
> Cliente 1
---->DEV
---->RELEASE
> Cliente 2 (Esta misma estructura se repetiria por cada cliente)
De esta forma evitaria tener ramas del proyecto común pero habría un riesgo muy alto ya que se estaría desarrollando sobre la main.
Cúal sería la mejor forma de estructurar el código para mi caso?
Espero haberme explicado.
Gracias y saludos,
Victor
El tema que comentas es radicalmente diferente, porque tu escenario difiere mucho del mio. Por lo que entiendo tienes como dos 1…n ramas de desarrollo. Tienes por un lado el desarrollo de tu librería Common Core que supongo que seguirá un versionado también de DEV, MAIN y RELEASE, y luego todas las ramas de los clientes, que también pueden estar con estas tres ramas, que deberían de consumir la rama RELEASE de tu proyecto Common Core. Eso te permite seguir con el desarrollo de tu librería común a las tres aplicaciones, ir sacando versiones estables sin molestarte en las incompatibilidades de esa librería con respecto a los demás desarrollos y después ir integrando en Main y RELEASE de Common core. Tienes que planteártelo de manera que sean como dos proyectos completamente separados, e internamente que vayas sacando reléase de una librería que los proyectos de los demás clientes consuman.
No dudes en seguir preguntado.
Hola Luis. Buen post. Me lo guardo en favoritos.
Yo he usado una tecnica de tokens parecida para la federacion de identidades(pre WIF) y me gustaria hacerte un par de preguntas ;)
¿Por cuanto tiempo es valido el token de autorizacion?
¿Como controlas que la aplicacion que se ha logado es la que esta haciendo los siguientes request con el token de autorizacion expedido?
Ups. Me adelante en hacer una de las preguntas. El ticket es valido por una hora.
Otra cosa. ¿Has pensado en algun tipo de sliding expiration para el ticket?
Hola Crowley!
Buena pregunta, es una cosa que tengo pendiente. Una de las opciones es que en cada petición devolver en las cabeceras una nueva autorización para el usuario. Así la API de cliente solamente obtiene la respuesta esperada, y en las cabeceras está el token de autorización actualizado.
Ya pondré como está hecha la API de cliente para que lo podáis ver.
El lunes 3 de septiembre estuve con la gente del CIIN dando una charla sobre desarrollo de aplicaciones
Luis gracias, me has resuelto una duda (muy tonta de mi parte) pero me ha quedado más claro que el agua :D
Que duda era Bruno? Compártela con la comunidad :)
Una chorrada > la tabla final con los tamaños serializados :D
Vamos con una segunda retahíla de enlaces relacionados con Windows Phone 7.5 (Mango). En este caso y
Best practices de Nokia para desarrollar apps de Windows Phone con 256MB de RAM : De hecho hay consejos
Después de 5 años de éxito en Italia, el 24 de Marzo se ha celebrado simultáneamente
Después de 5 años de éxito en Italia, el 24 de Marzo se ha celebrado simultáneamente en Madrid
Muy interesante, Luis.
¿Habéis usado algún profiler para saber qué optimizar o habéis tenido que hacerlo a ojo?
Hola Juanma, pues en principio hemos usado el profiler que viene con Internet Explorer en las herramientas de desarrollador y con el profiler de Google Chrome.
Eso lo que te mide son las ejecuciones de los método y donde se tarda más tiempo y con eso identificas donde tienes que empezar a depurar.
Luis Guerrero.
Nunca se me había ocurrido mirar ahí, y mira que estaba cerca :-)
Muchas gracias.
Recomiendo este artículo para mejorar el rendimiento de BLOCKED SCRIPT
www.etnassoft.com/.../mejorando-el-rendimiento-con-el-api-dom-desde-javascript
El Training Center grandioso !!!
En esta página
mashable.com/.../prometheus-html5-ie
se habla de ello y que algunas de las librerias utilizadas podrán dejarse a la comunidad en GitHub.
"Beyond just creating examples of great HTML5 content, Microsoft is also focused on sharing these skills back with the community.
Gavin says that Microsoft will be publishing some of the libraries used for the Training Center on GitHub in the near future. We think that’s pretty cool."
En estos temas, el evento de Pucela Tech Day es interesante,lástima no se emita vía streaming.
geeks.ms/.../pucela-tech-day.aspx
Trata en parte de un escenario de integración continúa , aunque creo no tratará parte de este proceso de generación de releases.