T. *_*ter 5 concurrency multithreading asynchronous silverlight-4.0
让我们暂时搁置一下,是否应该在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();
}
Run Code Online (Sandbox Code Playgroud)
正如你期望在MSDN上阅读ManualResetEvent,"当控制线程完成活动时,它调用Set方法来表示等待线程可以继续.",当在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不同?这可能是微软对异步设计模式的执行吗?还是有什么我想念的?
谢谢
Silverlight 中的网络回调将始终到达其发起的同一线程中。例如,如果您在 UI 线程上(即在按钮单击事件上)创建 WebClient.DownloadStringAsync,则回调调用将排队等待在同一 UI 线程上传递。但是,您的调用mre.WaitOne()
会阻塞 UI 线程,因此永远不会调用回调,并且mre.Set()
调用永远不会发生。
所以,是的,这是网络调用异步性的一种强制 - 你确实不能进行同步调用,即使它们看起来是同步的。
归档时间: |
|
查看次数: |
1247 次 |
最近记录: |