Вы можете использовать ManualResetEvent :
public string Download()
{
var manualEvent = new ManualResetEvent(false);
WebClient client = new WebClient();
var result = string.Empty;
client.DownloadStringCompleted += (sender, e) =>
{
if (e.Error != null)
{
result = e.Result;
}
manualEvent.Set();
};
client.DownloadStringAsync(new Uri(Application.Current.Host.Source.AbsoluteUri + "\\PHP\\GetAdmins.php"));
// block while the download is completed and the event is signaled or
// timeout after 30 seconds
if (!manualEvent.WaitOne(TimeSpan.FromSeconds(30)))
{
// timeout
}
return result;
}
Обратите внимание, что блокировка основного потока является плохой практикой, поскольку он блокирует пользовательский интерфейс.Лучшим способом было бы просто обработать результаты в обработчике события завершения загрузки.И поскольку этот обработчик выполняется в потоке, отличном от потока пользовательского интерфейса, не забудьте маршалировать любые вызовы, которые обновляют пользовательский интерфейс в основном потоке.
Рекомендуемый пример:
public void string Download()
{
var manualEvent = new ManualResetEvent(false);
WebClient client = new WebClient();
client.DownloadStringCompleted += (sender, e) =>
{
if (e.Error != null)
{
Dispatcher.BeginInvoke(() =>
{
ResultLabel.Text = e.Result;
});
}
else
{
Dispatcher.BeginInvoke(() =>
{
ResultLabel.Text = e.Error.ToString();
});
}
};
var url = new Uri(Application.Current.Host.Source.AbsoluteUri + "\\PHP\\GetAdmins.php");
client.DownloadStringAsync(url);
}
Таким образом, вы больше не блокируете основную резьбу, а пользовательский интерфейс остается текучим.После завершения асинхронной операции вы обновляете пользовательский интерфейс с помощью результата, направляя вызов в поток пользовательского интерфейса с помощью метода Dispatcher.BeginInvoke .