System.Net.WebClient 问题

发布于 2024-10-27 02:50:10 字数 643 浏览 1 评论 0原文

我正在编写一个必须访问 MySQL 数据库的程序。为此,我编写了一个 PHP WebService 来获取表中的所有值。我遇到的问题是我正在用 C# 编写一个函数来获取这些值。我希望该函数等待,直到调用 DownloadStringCompleted 事件的事件处理程序,然后返回值。我是这样做的:

WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadCompletedHandler);
client.DownloadStringAsync(new Uri(Application.Current.Host.Source.AbsoluteUri + "\\PHP\\GetAdmins.php"));
while (DownloadCompleted == false) { }
return DownloadResult;

但这会使程序挂起。

我需要一些东西来使程序的该部分暂停,直到 DownloadConpleted = true。

我正在运行 Visual Studio Ultimate 2010,我正在制作 Silverlight 应用程序,如果有任何帮助,我们将不胜感激。

I am writing a program that has to access a MySQL database. To do this I wrote a PHP WebService to get all the values in a table. The problem I am having is that I am writing a function in C# to get those values. I want the function to wait until a event handler on the DownloadStringCompleted event is called, then return the values. I did it like this:

WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadCompletedHandler);
client.DownloadStringAsync(new Uri(Application.Current.Host.Source.AbsoluteUri + "\\PHP\\GetAdmins.php"));
while (DownloadCompleted == false) { }
return DownloadResult;

But that makes the program hang.

I need something that will make that part of the program pause until DownloadConpleted = true.

I am running Visual Studio Ultimate 2010, I am making a Silverlight application, and any help will be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

离旧人 2024-11-03 02:50:10

您可以使用 ManualResetEvent - 从下载完成处理程序发出完成事件信号并让主线程等待它:

ManualResetEvent completionEvent = new ManualResetEvent(false);
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted +=delegate(object sender, DownloadStringCompletedEventArgs e)
{
    completionEvent.Set();
};

webClient.DownloadStringAsync(new Uri(Application.Current.Host.Source.AbsoluteUri + "\\PHP\\GetAdmins.php"));
completionEvent.WaitOne();

这回答了你的问题,但它仍然会让 UI 线程等待 - 你真的必须接受 Silverlight 的异步,所以努力寻找一个解决方案在 DownloadStringCompleted 事件处理程序中更新您的模型 - 这样您就不必使用拐杖,并且您的应用程序将执行得更好。

You could use a ManualResetEvent - signaling the completion event from the download completion handler and making the main thread wait on it:

ManualResetEvent completionEvent = new ManualResetEvent(false);
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted +=delegate(object sender, DownloadStringCompletedEventArgs e)
{
    completionEvent.Set();
};

webClient.DownloadStringAsync(new Uri(Application.Current.Host.Source.AbsoluteUri + "\\PHP\\GetAdmins.php"));
completionEvent.WaitOne();

This answers your question, but it still will make the UI thread wait - you really have to embrace async with Silverlight, so work towards a solution that updates your model in the DownloadStringCompleted event handler - that way you don't have to use crutches and your application will perform much better.

倾城°AllureLove 2024-11-03 02:50:10

您可以使用 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;
}

请注意,阻止主线程线程是一种不好的做法,因为它会冻结 UI。更好的方法是简单地在下载完成事件处理程序中处理结果。由于此处理程序在与 UI 线程不同的线程上执行,因此不要忘记将更新 UI 的任何调用封送到主线程。

推荐示例:

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);
}

这样您就不再阻塞主线程,并且 UI 保持流畅。异步操作完成后,您可以通过使用 Dispatcher.BeginInvoke 方法。

You could use a 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;
}

Note that blocking the main thread is a bad practice because it will freeze the UI. A better way would be to simply handle the results in the download completed event handler. And because this handler is executed on a thread different than the UI thread don't forget to marshal any calls that update the UI to the main thread.

Recommended example:

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);
}

This way you are no longer blocking the main thread and the UI remains fluid. Once the asynchronous operation completes you update the UI with the result by marshalling the call to the UI thread using the Dispatcher.BeginInvoke method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文