讓我們暫時擱置一下,question是否應該在Silverlight應用程序的上下文中嘗試類似同步的操作。如果我在下面的代碼中使用的ManualResetEvent爲:爲什麼ManualResetEvent無法在使用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();
}
正如你所期望從閱讀ManualResetEvent on MSDN,「如果控制線程完成的活動,它調用設置方法,以表示該等待的線程可以繼續。」 ,當在w_DownloadStringCompleted中調用Set()時,控制權返回到開始在AsyncCall中等待的等待線程。這是使用.NET 4.0運行時發生的情況。 AsyncCall中的線程被阻塞,直到下載完成並調用Set。
如果我在Silverlight 4中運行同一段代碼,DownloadStringAsync將被調用,但控件永遠不會到達w_DownloadStringCompleted回調。一旦調用了WaitOne(),那麼AsyncCall中的那個線程就掛在那裏,並且啓動來處理DownloadStringAsync的線程永遠不會到達回調。我看到一個線程到達SL4中的下載回調的唯一方法是,如果AsyncCall的線程從AsyncCall返回。所以Set()永遠不會被調用。
爲什麼ManualResetEvent在Silverlight 4中無法按預期工作?它爲什麼不同於.NET 4? 這可能是微軟對異步設計模式的強制執行嗎? 或者有什麼我失蹤?
感謝
你在調試器中看到了什麼? – SLaks 2011-05-27 02:41:50
如果我點擊Break All,我看到調試器停留在WaitOne(),並且線程中只有一個線程。 – 2011-05-27 02:47:55