Давайте на время отложим вопрос о том, следует ли даже пытаться выполнять синхронные операции в контексте приложения Silverlight. Если я использую ManualResetEvent, как в следующем коде:
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();
}
Как и следовало ожидать от чтения ManualResetEvent на MSDN , «Когда управляющий поток завершает действие, он вызывает метод Set, чтобы сигнализировать, что ожидающие потоки могут продолжить.», Когда Set () имеет значение вызывается в w_DownloadStringCompleted, элемент управления возвращается в ожидающий поток, который начал ожидание в AsyncCall. Это то, что происходит при запуске .NET 4.0. Поток в AsyncCall блокируется до завершения загрузки и вызова Set.
Если я выполню тот же фрагмент кода в Silverlight 4, будет вызван DownloadStringAsync, но элемент управления никогда не достигнет обратного вызова w_DownloadStringCompleted. Как только вызывается WaitOne (), этот поток в AsyncCall просто висит там, и поток, запущенный для обработки DownloadStringAsync, никогда не достигает обратного вызова. Единственный способ, которым я видел поток, достигающий обратного вызова загрузки в SL4, - это если поток из AsyncCall возвращается из AsyncCall. Поэтому Set () никогда не вызывается.
Почему ManualResetEvent не работает должным образом в Silverlight 4? Почему он отличается от .NET 4?
Может быть, это применение Microsoft асинхронного шаблона проектирования?
Или мне чего-то не хватает?
Спасибо