6

こんにちは、Web サーバー上の php ファイルに url Get パラメーターを渡し、ファイルからの応答を待つ関数があります (通常は 10 ~ 20 秒かかります)。これらのGetリクエストを一度に約5つの異なるphpファイルに送信する必要があるため、これをループ内に配置したいのですが、ループに追加しようとすると、関数はファイルが応答を返すまでループを待機させます。次のものへ。

    public string HttpGet(string URI, string Parameters)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URI + Parameters);

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        StreamReader resStream = new StreamReader(response.GetResponseStream());
          return resStream.ReadToEnd().Trim();
    }

    private void SendCommand()
    {
        for( int i = 0; i <= 4; i++)
        {
            AddRTB(HttpGet(url, paramater));
        }
    }

前のリクエストが完了するのを待たずに、5 つのリクエストすべてを一度に送信する方法はありますか? (私はそれをスレッド化することを考えていましたが、悲しいことに、私は以前に触れたことがないので、どこから始めればよいかわかりません。)

4

4 に答える 4

9

GetResponse()メソッドを使用する代わりにBeginGetResponse()、非ブロッキング呼び出しである を使用できます。WebResponse最終的に戻ったときにオブジェクトを処理できるコールバックを受け取ります。リンクの例は、すべての応答が返されるまでメインスレッドを待機させる方法の良いアイデアを提供します。

于 2010-09-26T18:40:15.340 に答える
9

TPL を使用する 2 つのアプローチを次に示します。

最初は、結果にアクセスする前に、すべてのリクエストが完了するのを待ちます

var runningTasks = new List<Task<string>>();

for (int ii = 0; ii <= 4; ii++)
{
    var wreq = (HttpWebRequest)WebRequest.Create("..." + ii);

    var taskResp = Task.Factory.FromAsync<WebResponse>(wreq.BeginGetResponse, 
                                                    wreq.EndGetResponse, 
                                                    null);
    var taskResult = taskResp.ContinueWith(tsk => new StreamReader(tsk.Result.GetResponseStream()).ReadToEnd().Trim());
    runningTasks.Add(taskResult);
}

Task.WaitAll(runningTasks.ToArray());
IEnumerable<string> results = runningTasks.Select(tsk => tsk.Result);

2 つ目は、結果が入ってくるたびに何かを行います。

for (int ii = 0; ii <= 4; ii++)
{
    var wreq = (HttpWebRequest)WebRequest.Create("..." + ii);

    var taskResp = Task.Factory.FromAsync<WebResponse>(wreq.BeginGetResponse, 
                                                    wreq.EndGetResponse, 
                                                    null);
    taskResp.ContinueWith(tsk => new StreamReader(tsk.Result.GetResponseStream()).ReadToEnd().Trim())
            .ContinueWith((Task<string> trs) => 
                { 
                    var result = trs.Result;
                    DoSomthingWithTheResult(result);
                });
}
于 2010-09-26T21:37:57.993 に答える
1

GetResponse の代わりに、リクエスト クラスの BeginGetResonse メソッドを使用します。サンプルとドキュメントは、http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspxにあります。

于 2010-09-26T18:44:23.763 に答える
0

Async メソッドでWebClientを使用します。

Begin\End の使用はより困難です。

于 2010-09-26T18:58:08.610 に答える