Categories
.NET

Notificaciones en PostgreSQL

Desde la versión 8 de este magnífico ORDBMS, existe un mecanismo que permite enviar y recibir notificaciones de manera muy simple.

code:

test=# LISTEN foo;
LISTEN
test=# NOTIFY foo;
NOTIFY
Notificación asíncrona «foo» recibida del proceso de servidor con PID 8872.
test=#

Esta característica -como menciona la documentación- es especialmente útil cuando existen procesos que deben estar englobados por una transacción, ejm. enviar un mail luego de la ejecución satisfactoria de un conjunto de procesos críticos.

A continuación un pequeño ejemplo realizado con el proveedor Npgsql, que implementa la caracterísca mencionada.

csharp:

// Encargado de 'escuchar' las notificaciones
using System;
using Npgsql;
using System.Net.Mail;
using System.Net;

namespace listener
{
    class Program
    {
        static void Main(string[] args)
        {
            NpgsqlConnection connection =
                new NpgsqlConnection("uid=alex;pwd=***;server=localhost;encoding=unicode;SyncNotification=true;database=test;");

            connection.Notification += new NotificationEventHandler(connection_Notification);

            // Escuchar las notificaciones con el nombre 'proceso_largo'
            using (NpgsqlCommand command =new NpgsqlCommand("LISTEN proceso_largo;", connection))
            {
                connection.Open();
                command.ExecuteNonQuery();
            }

            Console.WriteLine("Esperando notificaciones...");
        }

        static void connection_Notification(object sender, NpgsqlNotificationEventArgs e)
        {
            Console.WriteLine("Notificación Recibida: {0}\t{1}", e.Condition, e.PID);

            // Hacer algo útil

            SmtpClient client =new SmtpClient("smtp.empresa.com");
            client.Credentials =new NetworkCredential("usuario@empresa.com", "password");

            client.Send(
                "aplicacion_x@empresa.com",
                "logs@empresa.com",
                "Notificación aplicación_x",
                "Notificación: " + e.Condition + "\tPID : " + e.PID // ...
                );
        }
    }
}

Un cliente cualquiera:

csharp:

using System;
using Npgsql;
using System.Threading;

namespace app
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Iniciar Aplicación - Presione una tecla...");
            Console.Read();

            using (NpgsqlConnection connection =
                new NpgsqlConnection("uid=alex;pwd=***;server=localhost;encoding=unicode;database=test;"))
            {
                NpgsqlTransaction transaction = null;

                try
                {
                    connection.Open();
                    transaction = connection.BeginTransaction();

                    NpgsqlCommand command =new NpgsqlCommand("select current_date;", connection, transaction);

                    Console.WriteLine("Recuperando la fecha");
                    command.ExecuteScalar(); // hacer algo

                    Console.WriteLine("Enviando notificación - Transacción NO 'comprometida'.");
                    command.CommandText = "NOTIFY proceso_largo;";
                    command.ExecuteNonQuery(); // No ejecuta la notificación

                    // Continúa la transacción
                    Thread.Sleep(2000);
                   
                    transaction.Commit();
                    Console.WriteLine("Transacción 'comprometida', recien se envía la notificación 'proceso_largo'");
                }
                catch (NpgsqlException)
                {
                    if (transaction != null)
                        transaction.Rollback();
                    throw;
                }
            }
            Console.Read();
        }
    }
}

Además de las cosas mencionadas sobre esta característica de PostgreSQL, también podría servir como un mecanismo para que el Cache tenga datos coherentes.

Nota: Disculpen si encuentran malas prácticas de programación :-).

Elementos utilizados

Categories
.NET

ClickOnce y Firefox

La implementación ClickOnce permite publicar aplicaciones basadas en Windows en un servidor Web o en recurso compartido de archivos de red para simplificar la instalación. Visual Studio ofrece compatibilidad total para la publicación y actualización de aplicaciones implementadas con ClickOnce. La implementación ClickOnce está disponible para los proyectos creados con Visual Basic, Visual C# y Visual J#, pero no para Visual C++

Fuente: MSDN.

Leyendo uno de los mensajes de la lista de desarrollo de mono, me enteré que existe -desde hace un buen tiempo- una extensión para Firefox, que permite instalar las aplicaciones desplegadas con ClickOnce de una manera similar a lo que se hace con IE.

Sin duda una extensión muy útil para los zealots de .NET y Firefox. 😀

Categories
.NET

Mono 1.1.17

Acaba de liberarse la versión 1.1.17 de mono, una de las novedades más importantes de este release es que las versiones anteriores del compilador y runtime de Visual Basic .NET -hechas en C#- han sido eliminadas en favor de un nuevo runtime y compilador, ambos desarrollados íntegramente en Visual Basic .NET. Otra de las "novedades" es que mi primer y muy simple parche ha sido incluido en esta versión :-P.

Las descargas están disponibles en http://www.mono-project.com/Downloads

Categories
.NET Quiz

Quiz: Números aleatorios en .NET

La siguiente porción de código será usado para determinar el ganador del sorteo del voucher para un exámen de certificación Microsoft

csharp:

using System;
using System.Collections.Generic;
using System.IO;

class Participante
{
    private string Nombre, Email;
    public Participante(string nombre, string email)
    {
        Nombre = nombre;
        Email = email;
    }
    public override string ToString()
    {
        return string.Format("Nombre: {0}\t\tEmail: {1}", Nombre, Email);
    }
}
class Program
{
    static void Main(string[] args)
    {
        StreamReader reader = null;
        try
        {
            reader = new StreamReader("sorteo.txt");
            List<Participante> participantes = new List<Participante>();
            string line;

            while ((line = reader.ReadLine()) != null)
            {
                participantes.Add(new Participante(line.Split(',')[0], line.Split(',')[1]));
                Console.WriteLine(participantes[participantes.Count - 1]);
            }
           
            int ganador = ObtenerGanador(participantes.Count);

            Console.WriteLine("\n\nEl ganador es: {0}", participantes[ganador]);
        }
        finally
        {
            if (reader != null)
                reader.Close();
        }
    }
    public static int ValorAleatorio()
    {
        int semilla = DateTime.Now.Millisecond;
        Random rnd = new Random(semilla);
       
        int maximo = rnd.Next(0, semilla) * semilla;
       
        return rnd.Next(0, maximo % int.MaxValue);
    }
    public static int ObtenerGanador(int numeroParticipantes)
    {
        int ganador = 0;
        for (int i = 0; i < numeroParticipantes; i++)
            ganador += ValorAleatorio();

        return ganador % numeroParticipantes;
    }
}

El archivo sorteo.txt, tiene la siguiente estructura:

code:

Nombre Apellidos,Email
Nombre Apellidos,Email
Nombre Apellidos,Email

Determinen si el código mostrado sirve o no para los propósitos antes mencionados, si observan algún comportamiento raro, comenten abajo indicando las correcciones del caso.

Pueden descargar el código en C# o VB, para compilarlo -como se habrán dado cuenta- necesitan el .NET Framework 2.0

Nota: El código se ejecutará en una máquina con procesador AMD Athlon 64 3200+ y 1GB RAM.

Categories
.NET Varios

Sorteo de voucher para un examen de certificación Microsoft

Actualización: Ya existe un ganador del sorteo.

Actualización: El sorteo se realizará a las 15:30 horas (GMT-5) por motivos de trabajo, pido las disculpas del caso por no comunicar con anterioridad la hora.

Actualización: Verifica la validez del código que se utilizará para el sorteo!

Como premio a nuestros ¿asiduos? lectores :-), vamos a sortear un voucher válido sólo para un examen de la nueva generación de certificaciones de Microsoft.

El sorteo se realizará el 28 de Agosto del 2006, para participar sólo dejen un comentario (pongan los datos correctos en el formulario).

Nota 1: El voucher es válido hasta el 04 de Octubre, así que se sugiere tener un nivel adecuado para este tipo de exámenes.

Nota 2: Abstenerse las personas que no vivan cerca o no tengan las posibilidades de ir a un centro de exámenes autorizado (consultar en www.prometric.com o www.vue.com), de este modo evitamos desperdiciar el voucher.