2012-09-21 83 views
2

C#,.Net 4.5。我有一個包含要處理的對象的隊列。處理包括使用在對象的一個​​字段中指定的URL來獲取數據。在操作過程中,可以將新對象添加到隊列中。當我嘗試使用網絡異步工作時,我遇到了一個問題。任務<WebResponse>。等待永遠

這是最小的代碼。

public partial class Form1 : Form 
{ 
    private void button1_Click(object sender, EventArgs e) 
    { 
     string[] urls = { "http://www.stackoverflow.com/", 
          "http://www.google.com/", 
          "http://www.microsoft.com/" }; 
     int i = 0; 
     Queue<MyClass1> queue = new Queue<MyClass1>(); 

     HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(urls[i]); 
     webRequest.Proxy.Credentials = CredentialCache.DefaultCredentials; 
     queue.Enqueue(new MyClass1(urls[i], webRequest.GetResponseAsync())); 

     while (queue.Count > 0) 
     { 
      MyClass1 o = queue.Dequeue(); 
      o.RespTask.Wait(); 
      Debug.Print("Url: {0}, bytes: {1}", o.Url, 
       o.RespTask.Result.ContentLength); 

      i++; 
      if (i < urls.Length) 
      { 
       webRequest = (HttpWebRequest)WebRequest.Create(urls[i]); 
       webRequest.Proxy.Credentials = CredentialCache.DefaultCredentials; 
       queue.Enqueue(new MyClass1(urls[i], webRequest.GetResponseAsync())); 
      } 
     } 
    } 
} 

public class MyClass1 
{ 
    public MyClass1() { } 
    public MyClass1(string url, Task<WebResponse> respTask) 
    { 
     Url = url; 
     RespTask = respTask; 
    } 

    public string Url; 
    public Task<WebResponse> RespTask; 
} 

該代碼掛在o.RespTask.Wait();循環的第三次迭代。在此調用之前,o.RespTask.Status具有值WaitingForActivation並等待永遠持續。我究竟做錯了什麼?

UPDATE。我檢查了3個盒子上的代碼。在其中兩個(Win7 32位和Win7 64位)程序掛起。在第三個(Win7的64位)一切工作正常。在我看來,很奇怪。

+0

我沒有看到你描述的行爲,你的代碼對我來說工作正常。 – svick

+0

@svick我再次嘗試。我啓動了Visual Studio Express 2012 for Desktop,創建了一個新項目(C#,Windows窗體),複製了消息中的代碼,運行程序。在輸出窗口行中看到: 'Url:http://www.stackoverflow.com/,bytes:209830' 'Url:http://www.google.com/,bytes:-1' 之後,該程序掛起。 Windows 7,32位。 – lazymf

回答

1

此代碼已經停止這樣的修改後掛斷:

... 
Debug.Print("Url: {0}, bytes: {1}", o.Url, 
    o.RespTask.Result.ContentLength); 

o.RespTask.Result.Close(); 

i++; 
... 

我的錯誤是,我沒有注意一個事實,即調用HttpWebResponse類的Close方法是必須的。