我在一个非常简单的Silverlight 4应用程序中有以下代码。
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var result = string.Empty;
var mutex = new AutoResetEvent(false);
var wc = new WebClient();
wc.DownloadStringCompleted += (s, args) => {
result = args.Result;
mutex.Set();
};
wc.DownloadStringAsync(new Uri("http://localhost/SilverlightApplication2.Web/SilverlightApplication2TestPage.aspx", UriKind.Absolute));
mutex.WaitOne();
MessageBox.Show(result);
}
无论出于何种原因,永远不会调用mutex.Set(),因此mutex.WaitOne()会被锁定。我错过了什么?我也尝试过ManualResetEvent。
谢谢, 兰德尔
UPDATE1:
如果我执行以下操作,它会按预期工作。
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem(GetIt);
}
private void GetIt(object state)
{
var result = string.Empty;
var mutex = new AutoResetEvent(false);
var wc = new WebClient();
wc.DownloadStringCompleted += (s, args) => {
result = args.Result;
mutex.Set();
};
wc.DownloadStringAsync(new Uri("http://localhost/SilverlightApplication2.Web/SilverlightApplication2TestPage.aspx", UriKind.Absolute));
mutex.WaitOne();
Dispatcher.BeginInvoke(() => MessageBox.Show(result));
}
似乎UI线程存在导致回调无法执行的问题。
答案 0 :(得分:0)
你这样做的顺序错误:
首先,您等待阻止代码的AutoResetEvent。然后,您希望启动永远不会发生的异步操作,因为您仍在等待mutex.WaitOne()
。
只需将wc.DownloadStringAsync(new ...
行移到mutex.WaitOne();
答案 1 :(得分:0)
在启动之前,您似乎正在等待下载完成。
我认为您不能使用AutoResetEvent来执行此操作,因为您无法摆脱wc.DownloadStringAsync
在mutex.WaitOne()
启动之前完成的竞争条件,您将永远等待。 ManualResetEvent可以工作,但是如果它们存在,互斥加一个条件变量会更好。
答案 2 :(得分:0)
以下是答案:http://www.codeproject.com/KB/silverlight/SynchronousSilverlight.aspx
您无法阻止Silverlight中的UI线程。