2012-02-21 14 views
6

tôi cần phải thực hiện yêu cầu async đến tài nguyên web và sử dụng ví dụ từ trang này (link to full example):HttpWebRequest.BeginGetResponse

HttpWebRequest myHttpWebRequest= (HttpWebRequest)WebRequest.Create("http://www.contoso.com"); 
RequestState myRequestState = new RequestState(); 
myRequestState.request = myHttpWebRequest; 
// Start the asynchronous request. 
IAsyncResult result= 
     (IAsyncResult) myHttpWebRequest.BeginGetResponse(new AsyncCallback(RespCallback),myRequestState); 

Nhưng khi tôi đang thử nghiệm các ứng dụng đóng băng thực hiện (trên 2-3 giây) trên dòng cuối cùng của mã này (tôi có thể xem nó bằng trình gỡ lỗi).

Tại sao? Đó là sai lầm của tôi hoặc nó là một hành vi tiêu chuẩn của chức năng?

Trả lời

6

Bạn có thể thử, tôi chắc chắn thats tốt hơn

private void StartWebRequest(string url) 
{ 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
    request.BeginGetResponse(new AsyncCallback(FinishWebRequest), request); 
} 

private void FinishWebRequest(IAsyncResult result) 
{ 
    HttpWebResponse response = (result.AsyncState as HttpWebRequest).EndGetResponse(result) as HttpWebResponse; 
} 

Bởi vì chủ đề chross của textbox'value, Nhưng đây là ứng dụng WPF tôi sẽ gắn lại thẻ này, btw bạn có thể sử dụng WebClient như

private void tbWord_TextChanged(object sender, TextChangedEventArgs e) 
    { 
     WebClient wc = new WebClient(); 
     wc.DownloadStringCompleted += HttpsCompleted; 
     wc.DownloadStringAsync(new Uri("http://en.wikipedia.org/w/api.php?action=opensearch&search=" + tbWord.Text)); 
    } 
    private void HttpsCompleted(object sender, DownloadStringCompletedEventArgs e) 
    { 
     if (e.Error == null) 
     { 

      //do what ever 
      //with using e.Result 
     } 
    } 
+0

Thông số IAsyncResult trong phương pháp thứ hai là gì? Kết quả của yêu cầu gọi.BeginGetResponse()? – demas

+0

Như tôi thấy nó không thay đổi bất cứ điều gì. Đây là mã đầy đủ http://pastebin.com/trvq1qza. Cửa sổ GUI đóng băng trên dòng 18. – demas

+0

@demas i cập nhật câu trả lời. hoạt động trên tôi không đóng băng –

1

Bạn có thể sử dụng tính năng Thêm nền làm việc trong DoWork

2

Phản hồi xảy ra trên một chuỗi riêng biệt. Winforms không phải là đa luồng an toàn, vì vậy bạn sẽ phải gửi cuộc gọi trên cùng một chuỗi với biểu mẫu.

Bạn có thể thực hiện việc này bằng cách sử dụng vòng lặp nội bộ của cửa sổ. May mắn thay, .NET cung cấp một cách để làm điều này. Bạn có thể sử dụng các phương thức Invoke hoặc BeginInvoke của control để thực hiện điều này. Trước đây chặn luồng hiện tại cho đến khi chuỗi giao diện người dùng hoàn tất phương thức được gọi. Sau đó không đồng bộ như vậy. Trừ khi có dọn dẹp để làm, bạn có thể sử dụng thứ hai để "cháy và quên"

Để làm việc theo cách này, bạn sẽ cần tạo phương thức được gọi bởi BeginInvoke và bạn sẽ cần một đại biểu để trỏ đến phương pháp đó.

Xem kiểm soát.Kéo và kiểm soát.Bắt đầuInvoke trong MSDN để biết thêm chi tiết.

Có một mẫu tại liên kết này: https://msdn.microsoft.com/en-us/library/zyzhdc6b(v=vs.110).aspx

Cập nhật: Như tôi đang xem hồ sơ của tôi, vì tôi đã quên tôi đã có một tài khoản ở đây - tôi nhận thấy điều này và tôi nên thêm: Bất cứ điều gì trong quá khứ 3.5 hoặc khi họ đã thay đổi đáng kể các mô hình luồng không đồng bộ ở đây là ra khỏi wheelhouse của tôi. Tôi chuyên nghiệp, và trong khi tôi vẫn yêu thích nghề thủ công, tôi không làm theo mọi tiến bộ. Những gì tôi có thể cho bạn biết là nên hoạt động ở tất cả các phiên bản .NET nhưng có thể không phải là đỉnh cao tuyệt đối của hiệu suất 4.0 và cao hơn hoặc trên Mono/Winforms-thi đua nếu vẫn còn xung quanh. Về mặt tươi sáng, mọi lượt truy cập thường sẽ không tệ bên ngoài các ứng dụng máy chủ và thậm chí bên trong nếu threadpool đang thực hiện công việc của mình. Vì vậy, không tập trung tối ưu hóa nỗ lực ở đây trong hầu hết các trường hợp và có nhiều khả năng hoạt động trên nền tảng "bị gỡ xuống" mà bạn thấy đang chạy những thứ như gói di động C# mặc dù tôi phải xem xét để chắc chắn và hầu hết không chạy winforms một số vòng tin nhắn quay và điều này cũng hoạt động ở đó. Về cơ bản, điều này không phải là "câu trả lời hay nhất" cho các nền tảng mới nhất trong mọi trường hợp cuối cùng. Nhưng nó có thể di động hơn trong trường hợp đúng. Nếu điều đó giúp một người tránh mắc lỗi thiết kế, thì nó đáng để tôi viết nó. =)

1

Đó là hành vi tiêu chuẩn.

Từ documentation on HttpWebRequest.BeginGetResponse Method:

Phương pháp BeginGetResponse đòi hỏi một số nhiệm vụ thiết lập đồng bộ để hoàn thành (độ phân giải DNS, phát hiện proxy, và kết nối TCP socket, ví dụ) trước khi phương pháp này trở nên không đồng bộ. [...] có thể mất thời gian đáng kể (tối đa vài phút tùy thuộc vào cài đặt mạng) để hoàn tất các tác vụ thiết lập đồng bộ ban đầu trước khi ngoại lệ cho lỗi được ném hoặc phương thức thành công.

Để tránh chờ đợi cho các thiết lập, bạn có thể sử dụng HttpWebRequest.BeginGetRequestStream Method nhưng lưu ý rằng:

ứng dụng của bạn không thể kết hợp các phương pháp đồng bộ và không đồng bộ cho một yêu cầu cụ thể. Nếu bạn gọi phương thức BeginGetRequestStream, bạn phải sử dụng phương thức BeginGetResponse để lấy phản hồi.