sábado, 6 de febrero de 2016

¿Problemas de sincronización en Microsoft Edge?

Normalmente no publico tips o consejos sobre sistemas operativos y dispositivos. Sin embargo hacía tienpo que un problema es estaba molestando bastante y ya que con lai nestimable ayuda de Internet lo solucione quiero compartir dicha solución.
Vereis: En el ámbito personal uso principalmente dos equipos: Una surface pro 3 y un ordenador de sobremesa, ambos con Windows 10. Todo funcionaba con normalidad hasta que hace algunas semanas empece a notar que los favoritos y la lista de lectura de Edge (si, uso Edge, llamadme raro) no estaban sincronizados. Si lo habían estado en el pasado, pero esa relación parecía haber terminado Broken heart

Me dispuse a ver si algún setting había cambiado en Edge, y al ir a la configuración vi que la opción de sincronización estaba desactivada, y además en gris, sin permitirme modificarla:

EdgeSync1

Siguiendo las instrucciones fui a la configuración de Windows (pinche en Settinhs), para comprobar que allí todo estaba bién, la sincronización estaba activada:

EdgeSync2

Este mismo escenario estaba en los dos equipos… ¿Que pasaba?  No lo se, estas son las cosas que me desesperan de Windows, pero bueno, un rato dse busqueda en internet me llevó a la solución: Editar en el registro (regedit.exe) la clave SyncPolicy que esta en la siguiente ruta:

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\SettingSync

El valor a asignar es el 1 (estaba a cero).

Una vez hecho ya pude activar la sincronización en Edge:

image

Y lo mas curioso: solo necesité hacerlo en uno de los equipos. Una vez lo hice en el primero(el desktop) los favoritos de Edge empezaron a sincronizarse. Fui a la surface y la setting de sincronización se había activado sola Smile

Si esto resuelve a alguién su problema… genial!

lunes, 2 de marzo de 2015

De los delegados a la lambdas 2: Rarezas

Vamos a continuar la serie dedicada a delegados y lambdas. Después de haber explicado los delegados y antes  de meternos con las lambdas, vamos a ver algunos aspectos "raros" o mejor dicho, menos conocidos de los delegados.

Delegate multicasting


Se trata de una característica que nos va a permitir almacenar más de un método en un delegado.
Para emplearla debemos utilizar el operador +=

   1:  class Program
   2:  {
   3:      delegate void delSaludo();
   4:   
   5:      static void Main(string[] args)
   6:      {
   7:          delSaludo miDel = Saludo1;
   8:          miDel += Saludo2;
   9:   
  10:          miDel();
  11:      }
  12:   
  13:      protected static void Saludo1()
  14:      {
  15:          Console.WriteLine("Este es el saludo 1");
  16:      }
  17:   
  18:      protected static void Saludo2()
  19:      {
  20:          Console.WriteLine("Este es el saludo 2");
  21:      }
  22:  }

La salida por pantalla correspondiente la podéis imaginar:
 
 
 
También podemos utilizar el operador -=
 
Hemos visto un ejemplo con métodos que no devuelven nada. Sin embargo he leído por ahí que si hacemos multicasting a métodos no void obtendremos un excepción. ¿Es esto cierto? Veámoslo
 
   1:  class Program
   2:  {
   3:      delegate int delOperacion(int a, int b);
   4:   
   5:      static void Main(string[] args)
   6:      {        
   7:          delOperacion miDelOp = Suma;
   8:          miDelOp += Mult;
   9:   
  10:          var res = miDelOp(2, 3);
  11:          Console.WriteLine("Resultado={0}",res);
  12:      }
  13:   
  14:      protected static int Suma(int a, int b)
  15:      {
  16:          return a + b;
  17:      }
  18:   
  19:      protected static int Mult(int a, int b)
  20:      {
  21:          return a * b;
  22:      }
  23:  }
 
¿Qué salida obtendremos?
 
 
 
No hay excepción, y el valor que queda en la variable es el valor retornado por el último método invocado. ¿Curioso no?

Delegate async invocation

 
Los delegados pueden ser ejecutados de modo asíncrono. Esto hará que un nuevo thread sea creado para nosotros y que este nuevo thread sea el que ejecute el método almacenado en el delegado.
 
La forma general de usarlo es la siguiente.
 
       delegado.BeginInvoke(params, asyncCallback,  object)
 
Si no vamos a usar un callback podemos fijarlo a nulo, junto con el último parámetro.
 
Un ejemplo:
 
   1:  class Program
   2:  {
   3:      delegate bool delMakeOperation(int param);
   4:      static void Main(string[] args)
   5:      {
   6:          delMakeOperation d1 = MakeLonggOp;
   7:   
   8:          Console.WriteLine("Main (threadId={0}) va a llamar al delegado", Thread.CurrentThread.ManagedThreadId);
   9:          d1.BeginInvoke(6, null, null);
  10:          Thread.Sleep(1000);
  11:          Console.WriteLine("Main acaba");
  12:      }
  13:   
  14:      protected static bool MakeLonggOp (int param)
  15:      {
  16:          Console.WriteLine("MakeLonggOp empieza (threadId={0})",Thread.CurrentThread.ManagedThreadId);
  17:          Thread.Sleep(param * 1000);
  18:          Console.WriteLine("MakeLonggOp acaba");
  19:              
  20:          return true;
  21:      }
  22:  }
 
La salida:
 
 
 
Como veis hay 2 threads ejecutándose...  sin embargo la llamada asíncrona al delegado nunca termina, ya que mi aplicación de consola finaliza antes. ¿Cómo esperamos por la finalización del delegado? Hay varias formas
 
  • Esperando la finalización asíncrona con EndInvoke
  • Esperando a la finalización asíncrona con WaitHandle 
  • Haciendo pooling ...no me gusta :-(
  • Ejecutando un callback
 
Aquí tenéis código para todas ellas:
 
   1:  class Program
   2:  {
   3:      delegate bool delMakeOperation(int param);
   4:      static void Main(string[] args)
   5:      {
   6:          Espera_EndInvoke();
   7:          Espera_WaitHandle();
   8:          Espera_Pooling();
   9:          Llamando_Callback();
  10:      }
  11:   
  12:      protected static bool MakeLonggOp(int param)
  13:      {
  14:          Console.WriteLine("MakeLonggOp empieza (threadId={0})", Thread.CurrentThread.ManagedThreadId);
  15:          Thread.Sleep(param * 1000);
  16:          Console.WriteLine("MakeLonggOp acaba");
  17:   
  18:          return true;
  19:      }
  20:   
  21:      protected static void Espera_EndInvoke()
  22:      {
  23:          delMakeOperation d1 = MakeLonggOp;
  24:   
  25:          Console.WriteLine("Main (threadId={0}) va a llamar al delegado", Thread.CurrentThread.ManagedThreadId);
  26:          var asyncRes=d1.BeginInvoke(6, null, null);
  27:          var res = d1.EndInvoke(asyncRes); //Esta llamada es bloqueante
  28:   
  29:          Console.WriteLine("Metodo asincrono acaba. Resultado={0}", res);
  30:      }
  31:   
  32:      protected static void Espera_WaitHandle()
  33:      {
  34:          delMakeOperation d1 = MakeLonggOp;
  35:   
  36:          Console.WriteLine("Main (threadId={0}) va a llamar al delegado", Thread.CurrentThread.ManagedThreadId);
  37:          var asyncRes = d1.BeginInvoke(6, null, null);
  38:   
  39:          asyncRes.AsyncWaitHandle.WaitOne();//Esta llamada es bloqueante 
  40:   
  41:          var res = d1.EndInvoke(asyncRes);
  42:   
  43:          Console.WriteLine("Metodo asincrono acaba. Resultado={0}", res);
  44:      }
  45:   
  46:      protected static void Espera_Pooling()
  47:      {
  48:          delMakeOperation d1 = MakeLonggOp;
  49:   
  50:          Console.WriteLine("Main (threadId={0}) va a llamar al delegado", Thread.CurrentThread.ManagedThreadId);
  51:          var asyncRes = d1.BeginInvoke(6, null, null);
  52:   
  53:          while (! asyncRes.IsCompleted)
  54:          {
  55:              Thread.Sleep(250);
  56:              Console.Write(".");
  57:          }
  58:   
  59:          //La ejecucion asincrona acabo
  60:   
  61:          var res = d1.EndInvoke(asyncRes);
  62:          Console.WriteLine("Metodo asincrono acaba. Resultado={0}", res);
  63:      }
  64:   
  65:      protected static void Llamando_Callback()
  66:      {
  67:          delMakeOperation d1 = MakeLonggOp;
  68:   
  69:          Console.WriteLine("Main (threadId={0}) va a llamar al delegado", Thread.CurrentThread.ManagedThreadId);
  70:          var asyncRes = d1.BeginInvoke(6, new AsyncCallback(CallbackMethod), "async state");
  71:   
  72:          Console.ReadLine();
  73:      }
  74:   
  75:      static void CallbackMethod(IAsyncResult ar)
  76:      {
  77:          // Recuperamos el delagdo
  78:          AsyncResult result = (AsyncResult)ar;
  79:          delMakeOperation del = (delMakeOperation)result.AsyncDelegate;
  80:   
  81:          string obj = (string)ar.AsyncState; //Objeto pasado cuando se hizo la llamada asíncrona. Obtendremos "async state" que es lo que se paso
  82:              
  83:          // Call EndInvoke to retrieve the results. 
  84:          var res = del.EndInvoke(ar);
  85:                          
  86:          Console.WriteLine("Metodo asincrono acaba. Resultado={0}", res);
  87:      }
  88:   
  89:  }
 
En todos los casos obtenemos una salida como la siguiente:
 
 
 
Como veis hay muchas formas de esperar por la finalización del método asíncrono. De todos modos hoy en día hay formas más elegantes de hacer programación asíncrona (¿te suena async & await?). Ya lo veremos! Prometo escribir al respecto.
 
Con esto dejamos los delegados, aquí tenéis el código completo.
 
En la siguiente entrada trataremos las lambdas!
 
 Post publicados en esta serie:
 
 
 
 

viernes, 20 de febrero de 2015

De los delegados a las lambdas 1: Comenzando

Inicio una nueva serie de post (3 en principio) dedicados a los delegados y las lambdas... que hace tiempo se convirtieron en algo imprescindible para todo desarrollador C#.

Empecemos por el principio: que es un delegado, métodos anónimos, predicados y todas esas cosas que algunos desarrolladores usan, sin llegar a comprender lo que hacen.

¿Qué es un delegado? 

 
Algo así (un poco de código vale mas que mil palabras):

   1:  delegate <return type> <delegate-name> <parameter list>

Un ejemplo:
 
   1:  delegate int delOperacionSobreEnteros(int num1, int num2);

Si eres de la vieja escuela habrás programado en C / C++ (que tiempos) así que lo más fácil es decir que es muy similar a un puntero a función.

Pero si no, te diré que un delegado es un tipo que permite almacenar un método. En el ejemplo anterior el delegado delOperacionSobreEnteros permite representar métodos que cumplan con su firma: recibe dos enteros como parámetros y devuelve un entero. Puesto que un delegado almacena un método, puede ser ejecutado.

Uno de los principales usos es definir delegados en los parámetros de un método, lo que nos permite mucha flexibilidad:

   1:  class Program
   2:  {
   3:      public delegate int delOperacionSobreEnteros(int num1, int num2);
   4:      static void Main(string[] args)
   5:      {
   6:   
   7:          delOperacionSobreEnteros d1 = OperacionSuma;
   8:          delOperacionSobreEnteros d2 = new delOperacionSobreEnteros(OperacionMultiplicacion);
   9:   
  10:          EjecutaOperacion(d1);
  11:          EjecutaOperacion(d2);            
  12:              
  13:          Console.ReadLine();
  14:      }
  15:   
  16:      protected static void EjecutaOperacion(delOperacionSobreEnteros delegado)
  17:      {
  18:          const int a=3;
  19:          const int b=2;
  20:              
  21:          Console.WriteLine("Vamos a llamar al delegado");
  22:          var res=delegado(a, b);
  23:          Console.WriteLine("a op b={0}", res);
  24:      }
  25:   
  26:      protected static int OperacionSuma(int a, int b)
  27:      {
  28:          return a + b;
  29:      }
  30:   
  31:      protected static int OperacionMultiplicacion(int a, int b)
  32:      {
  33:          return a * b;
  34:      }
  35:  }
 
Como veis tengo un método que se encarga de ejecutar operaciones (EjecutaOperacion). ¿Qué operación? La recibida como parámetro a través de un delegado. La salida del anterior ejemplo es la siguiente:
 

 
También podemos hacer que una propiedad de una clase sea un delegado...  seguro que se os ocurren más usos :-P
 

¿Y que es eso de los métodos anónimos?


Pues más de lo mismo, pero con sintaxis "reducida". Nos permiten asignar un bloque de código a un delegado, sin tener que declarar un método. Son por tanto métodos sin nombre, solo con cuerpo.

   1:  public delegate int delOperacionSobreEnteros(int num1, int num2);
   2:   
   3:  ...
   4:   
   5:  delOperacionSobreEnteros d3 = delegate (int a, int b)  { return a / b ;  };
   6:  var resd3=d3(10,2);
   7:  Console.WriteLine("10 / 2={0}", resd3);
 
Estos métodos anónimos han sido reemplazados por las lambdas, mucho más potentes y cómodos. Lo veremos en las siguientes entradas


Otros tipos de delegados

 
Si... hay más. ¿ habéis usado TaskFactory para ejecutar algo de un modo asíncrono ?
Pues bien, aunque tiene varias sobrecargas, vamos a fijarnos en estas:
 
   1:  public Task StartNew( Action action)
   2:  public Task StartNew<TResult>(Func<TResult>)  

La primera permite ejecutar código asíncrono que no devuelve nada. Veis que recibe un parámetro tipo Action
La segunda permite ejecutar código asíncrono que devolverá un valor, y recibe un parámetro tipo Func
 
¿Y que son action y Func?  Pues otros tipos de delegados.
 
Action <T1, T2,...> es un delegado que puede almacenar un método que recibe hasta 16 parámetros, pero que no retorna valor (void)
Func <T1,T2..., TResult>  también almacena un método con hasta 16 parámetros, pero puede devolver un valor
 
Veámos un ejemplo con Func:
 
   1:  Func<int, int, int> funcSuma = OperacionSuma;
   2:  var resFunc = funcSuma.Invoke(6, 7);
   3:  Console.WriteLine("6 + 7={0}", resFunc);
 
Como veis, me ahorro la definición del delegado y utilizo uno que ya viene de serie con el framework. ¿Más cómodo no?

¿Y predicate?

De nuevo es un delegado que viene definido en .NET Framework (msdn). En este caso se trata de un delegado que recibe un elemento como parámetros y que devuelve un booleano:

   1:  public delegate bool Predicate<in T>(
   2:      T obj
   3:  )

Se usa principalmente en ciertos métodos de filtrado sobre los tipos de datos Array y List. Mirad el siguiente ejemplo, creo que es autoexplicativo:  
 
 
   1:  Predicate<int> predMayor = MayorQue10;
   2:   
   3:  var lista = new List<int>() { 3, 6, 15, 45 };
   4:   
   5:  var listaFiltrada = lista.FindAll(predMayor);
   6:   
   7:  Console.WriteLine("Elementos de la lista mayores que 10:");
   8:  foreach(var elem in listaFiltrada)
   9:      Console.Write("{0} ", elem);
  10:   
  11:   
  12:  protected static bool MayorQue10 (int valor)
  13:  {
  14:      return (valor > 10);
  15:  }
 
 
Con esto terminamos, espero que lo anterior os resulte claro y útil.
 
Como siempre aquí os dejo el código.