gpt4 book ai didi

multithreading - 为什么 ManualResetEvent 无法在使用 Silverlight 4 的此同步调用中工作?

转载 作者:行者123 更新时间:2023-12-04 06:50:49 26 4
gpt4 key购买 nike

让我们暂时搁置,question是否应该在 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 on MSDN 时所期望的那样, “当控制线程完成事件时,它会调用 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()电话永远不会发生。

所以是的,这是对网络调用异步性的一种强制执行——你真的不能进行同步调用,即使它们看起来是同步的。

关于multithreading - 为什么 ManualResetEvent 无法在使用 Silverlight 4 的此同步调用中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6147288/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com