2010-09-26 32 views
6

Xin chào, tôi có một chức năng chuyển url Nhận tham số cho tệp php trên máy chủ web và chờ phản hồi từ tệp (thường mất 10-20 giây). Tôi muốn đặt điều này bên trong một vòng lặp vì tôi phải gửi các yêu cầu này đến khoảng 5 tệp php khác nhau cùng một lúc nhưng khi tôi cố gắng thêm nó vào vòng lặp, hàm làm cho vòng lặp chờ cho đến khi tệp trả về phản hồi trước khi nó đi Ngày kế tiếp.WebRequals không đồng bộ sử dụng C#

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

Có cách nào để tôi có thể gửi tất cả 5 yêu cầu cùng một lúc mà không phải chờ kết thúc trước? (Tôi đã nghĩ về việc đọc nó nhưng tôi chưa bao giờ chạm vào nó trước đây là tôi không biết bắt đầu từ đâu.)

+1

Threading là cách để thực hiện việc này, mặc dù bạn sẽ cần phải chờ tất cả 5 câu trả lời trước khi tiếp tục. – ChrisF

Trả lời

9

Thay vì sử dụng phương pháp GetResponse() bạn có thể sử dụng số BeginGetResponse(). Phải mất một cuộc gọi lại mà sau đó có thể xử lý các đối tượng WebResponse khi nó cuối cùng trở về. Ví dụ trong liên kết sẽ cung cấp cho bạn ý tưởng tốt về cách yêu cầu chủ đề chính chờ tất cả các phản hồi trả về.

0

Sử dụng WebClient bằng phương pháp Không đồng bộ.

Bắt đầu \ Kết thúc khó sử dụng hơn.

9

Dưới đây là hai cách tiếp cận sử dụng TPL.

Các chờ đợi đầu tiên cho tất cả các yêu cầu để hoàn thành trước khi bạn truy cập vào bất kỳ kết quả

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

và lần thứ hai làm điều gì đó với mỗi kết quả vì nó đi kèm trong:

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

+1. Ngay cả khi câu trả lời @ linuxuser27 không có gì sai, câu trả lời này tốt hơn cho câu hỏi và sẽ dễ thực hiện hơn nhiều. –

+0

+1 Thật vậy, phương thức 'ContinueWith()' là – linuxuser27

+0

Và điều này sẽ thay đổi thế nào nếu tôi cần gửi một số dữ liệu với yêu cầu HTTP POST bằng BeginGetRequestStream/EndGetRequestSteam? http://stackoverflow.com/questions/4190903 –

Các vấn đề liên quan