2

WebRequestを使用して単純なリクエストを実行していますが、応答が返されるまでアプリがハングします。これを修正するにはどうすればよいですか?

私はたくさんのトピックを読みました、そしてそれらはすべてスレッドを使うと言います。使い方がわかりません。誰かがユーザーインターフェイスをハングさせない次の例を提供できますか?

private string SimpleRequest(String url)
{
    WebRequest request = WebRequest.Create(url);
    WebResponse response = request.GetResponse();
    Stream stream = response.GetResponseStream();
    StreamReader reader = new StreamReader(stream);
    string result = reader.ReadToEnd();
    stream.Dispose();
    reader.Dispose();
    return result;
}

private void button1_Click(object sender, EventArgs e)
{
    String googleHtml = simpleRequest("https://facebook.com");
}

ありがとう!

4

4 に答える 4

8

C#5.0を使用している場合は、簡単すぎます

public async void Test1()
{
      WebClient wc = new WebClient();
      richTextBox1.Text =  await wc.DownloadStringTaskAsync("https://facebook.com");
}

メソッドを次のように変換することもできawaitableます

private Task<string> simpleRequest(String url)
{
    return Task.Factory.StartNew(() =>
        {
            WebRequest request = WebRequest.Create(url);
            WebResponse response = request.GetResponse();
            Stream stream = response.GetResponseStream();
            StreamReader reader = new StreamReader(stream);
            string result = reader.ReadToEnd();
            stream.Dispose();
            reader.Dispose();
            return result;
        });
}

と呼び出す

public async void Test2()
{
      richTextBox1.Text =  await simpleRequest("https://facebook.com");
}

C#の下位バージョンについては、他の回答を参照してください。

于 2012-08-26T16:39:58.927 に答える
3

メインUIスレッドでネットワークアクセスを行っています。UIには、UIをループして更新するメインスレッドがあります。そのスレッドでネットワークアクセスを行うと、UIは更新されず、メソッドが戻ってループを続行できるようになるまで、UIはハングしているように見えます。

バックグラウンドスレッドで作業を行うことを検討してください。.netでこれを行う簡単な方法の1つは、BackgroundWorkerクラスです。

公式ドキュメントには、その使用法の良い例があります。

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

BackgroundWorkerクラスを使用すると、別の専用スレッドで操作を実行できます。ダウンロードやデータベーストランザクションなどの時間のかかる操作により、ユーザーインターフェイス(UI)が実行中に応答を停止したように見える場合があります。レスポンシブUIが必要で、そのような操作に関連する長い遅延に直面している場合、BackgroundWorkerクラスは便利なソリューションを提供します。

于 2012-08-26T16:27:08.470 に答える
3

BackgroundWorkerUIスレッド以外のスレッドを使用するためにを使用できます。これがサンプルです。

進行状況をキャンセルまたは表示することもできます。

public partial class fmMain : Form
{
    private void btnrunBackgroundWorker_Click( object sender, EventArgs e )
    {
        // Create a background worker
        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += new DoWorkEventHandler( bw_DoWork );

        // run in another thread
        bw.RunWorkerAsync();     
    }

    private void bw_DoWork( object sender, DoWorkEventArgs e )
    {
        String facebookHtml = simpleRequest("https://facebook.com");
    }
}
于 2012-08-26T16:30:25.170 に答える
2

メインのUIスレッドがハングしないように、 BackgroundWorkerを使用する必要があります。

private void button1_Click(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync("https://facebook.com"); // start async operation
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    e.Result = simpleRequest(e.Argument.ToString()); // set result in async operation
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error == null)
    {
        // show result here
        // or access/manage result here
        MessageBox.Show(e.Result.ToString());
    }
    else
    {
        // manage/show error
        MessageBox.Show(e.Error.Message);
    }
}
private String simpleRequest(String url)
{
     // your code goes here
}

backgroundWorker1_ProgressChangedを実装して、ユーザーがwebSiteの読み込みの進行状況を確認できるようにすることもできます。(sideNote:ProgressChangedとContextの詳細については、この質問を参照してください)

于 2012-08-26T16:41:14.373 に答える