Dejemos de lado, por el momento, el question de si las operaciones sincrónicas deberían incluso intentarse dentro del contexto de una aplicación Silverlight. Si uso ManualResetEvent como en el siguiente código:¿Por qué ManualResetEvent no funciona en esta llamada síncrona usando Silverlight 4?
static string result;
static AutoResetEvent are = new AutoResetEvent(false);
static ManualResetEvent mre = new ManualResetEvent(false);
public static string AsyncCall()
{
string url = "https://stackoverflow.com/feeds/tag/silverlight";
WebClient w = new WebClient();
w.DownloadStringCompleted += new DownloadStringCompletedEventHandler(w_DownloadStringCompleted);
w.DownloadStringAsync(new Uri(url), url);
mre.WaitOne();
return result;
}
static void w_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
result = e.Result;
mre.Set();
}
Como era de esperar de la lectura de ManualResetEvent on MSDN, "Cuando el subproceso de control completa la actividad, se llama al método Set para señalar que los hilos de espera pueden proceder." , cuando se llama a Set() en w_DownloadStringCompleted, el control vuelve al hilo en espera que comenzó a esperar en AsyncCall. Esto es lo que sucede cuando se ejecuta esto con .NET 4.0. El hilo en AsyncCall se bloquea hasta que se completa la descarga y se llama a Set.
Si ejecuto el mismo código en Silverlight 4, se llamará a DownloadStringAsync, pero el control nunca alcanzará la devolución de llamada w_DownloadStringCompleted. Una vez que se llama a WaitOne(), ese hilo en AsyncCall simplemente se cuelga allí, y el hilo que despegó para procesar DownloadStringAsync nunca alcanza la devolución de llamada. La única forma en que he visto un hilo llegar a la devolución de llamada de descarga en SL4 es si el hilo de AsyncCall vuelve de AsyncCall. Entonces Set() nunca recibe una llamada.
¿Por qué ManualResetEvent no funciona como se esperaba en Silverlight 4? ¿Por qué difiere de .NET 4? ¿Es esto quizás la aplicación de Microsoft del patrón de diseño asincrónico? ¿O hay algo que me falta?
Gracias
¿Qué ves en el depurador? – SLaks
Si presiono Romper todo, veo que el depurador está bloqueado en WaitOne() y que solo hay un hilo en Subprocesos. –