【问题标题】:Task<WebResponse>.Wait lasts foreverTask<WebResponse>.Wait 永远持续
【发布时间】:2012-09-21 06:41:59
【问题描述】:

C#,.Net 4.5。我有一个包含要处理的对象的队列。处理包括使用在对象的字段之一中指定的URL获取数据。在操作过程中,可以将新对象添加到队列中。当我尝试使用网络异步进行工作时,我遇到了一个问题。

这是一个最低限度的代码。

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 并且等待永远持续。我做错了什么?

更新。我检查了 3 个盒子上的代码。在其中两个(Win7 32 位和 Win7 64 位)上,程序挂起。在第三个(Win7 64 位)上一切正常。在我看来这很奇怪。

【问题讨论】:

  • 我没有看到你描述的行为,你的代码对我来说很好。
  • @svick 我又试了一次。我启动了 Visual Studio Express 2012 for Desktop,创建了一个新项目(C#、Windows 窗体),从消息中复制了代码,运行了程序。在输出窗口中看到行:Url: http://www.stackoverflow.com/ , bytes: 209830Url: http://www.google.com/ , bytes: -1 之后,程序挂起。 Windows 7,32 位。

标签: c# .net-4.5


【解决方案1】:

经过这样的修改,这段代码不再挂起:

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

o.RespTask.Result.Close();

i++;
...

我的错误是我没有注意对HttpWebResponse类的Close方法的调用是必须的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-13
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多