gpt4 book ai didi

c# - HttpWebRequest 限制?或者实现不当

转载 作者:行者123 更新时间:2023-11-30 19:22:29 28 4
gpt4 key购买 nike

我正在尝试构建一个 c# 控制台应用程序,它将监视大约 3000 个 url(只需要知道 HEAD 请求返回 200,不一定是内容等)

我在这里的尝试是构建一个例程来检查 Web URL,循环并创建线程,每个线程都执行该例程。发生的情况是,如果我使用 <20 个线程运行,它大部分时间都执行正常,但如果我使用 >20 个线程,一些 url 会超时。我尝试将超时增加到 30 秒,同样发生。我运行此程序的网络能够执行 50 个 HTTP HEAD 请求(ISP 的 10MBIT 连接),并且在执行例程时 CPU 和网络运行速度都非常低。

当发生超时时,我在浏览器上测试同一个 IP,它工作正常,我反复测试了这个,在测试期间从来没有出现过“超时”url 实际上超时的情况。

我想运行 >20 个线程的原因是我想每 5 分钟执行一次此测试,其中一些 URL 需要整整 10 秒(如果超时设置得更高,则可能更长),我想确保它能够在 2-3 分钟内遍历所有 URL。

是否有更好的方法来检查 URL 是否可用,或者我是否应该查看系统/网络是否存在问题。

        while (rdr.Read())
{
Thread t = new Thread(new ParameterizedThreadStart(check_web));

t.Start(rdr[0]);


}

      static void check_web(object weburl)
{
bool isok;
isok = ConnectionAvailable(weburl.ToString());
}



public static bool ConnectionAvailable(string strServer)
{

try
{
strServer = "http://" + strServer;
HttpWebRequest reqFP = (HttpWebRequest)HttpWebRequest.Create(strServer);
reqFP.Timeout = 10000;
reqFP.Method = "HEAD";

HttpWebResponse rspFP = (HttpWebResponse)reqFP.GetResponse();
if (HttpStatusCode.OK == rspFP.StatusCode)
{
Console.WriteLine(strServer + " - OK");
rspFP.Close();
return true;
}
else
{
Console.WriteLine(strServer + " Server returned error..");
rspFP.Close();
return false;

}

}

catch (WebException x)
{
if (x.ToString().Contains("timed out"))
{
Console.WriteLine(strServer + " - Timed out");
}
else
{
Console.WriteLine(x.Message.ToString());
}

return false;

}

}

最佳答案

记住,你问过。

非常糟糕的实现。

  1. 不要那样创建线程。拥有比处理器内核更多的线程并没有什么好处。额外的线程几乎只会相互竞争,尤其是因为它们都在运行相同的代码。

  2. 您需要使用 block 来实现。如果您抛出异常(您很可能会抛出异常),那么您将泄漏资源。

  3. 返回 bool 值的目的是什么?你在某个地方检查它吗?无论如何,你的错误和异常处理都是一团糟。

    • 当您收到非 200 响应时,您不会显示错误代码。
    • 您正在与 Message 属性进行比较,以确定它是否超时。微软应该在“time”和“out”之间放一个空格来激怒你。
    • 当不是超时时,您只显示 Message 属性,而不是整个异常,并且 Message 属性已经是一个字符串,不需要您对其调用 ToString()。

下一批更改

这还没有完成,我不认为,但试试这个:

public static void Main()
{
// Don't mind the interpretation. I needed an excuse to define "rdr"
using (var conn = new SqlConnection())
{
conn.Open();
using (var cmd = new SqlCommand("SELECT Url FROM UrlsToCheck", conn))
{
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
// Use the thread pool. Please.
ThreadPool.QueueUserWorkItem(
delegate(object weburl)
{
// I invented a reason for you to return bool
if (!ConnectionAvailable(weburl.ToString()))
{
// Console would be getting pretty busy with all
// those threads
Debug.WriteLine(
String.Format(
"{0} was not available",
weburl));
}
},
rdr[0]);
}
}
}
}
}

public static bool ConnectionAvailable(string strServer)
{
try
{
strServer = "http://" + strServer;
var reqFp = (HttpWebRequest)WebRequest.Create(strServer);
reqFp.Timeout = 10000;
reqFp.Method = "HEAD";

// BTW, what's an "FP"?
using (var rspFp = (HttpWebResponse) reqFp.GetResponse()) // IDisposable
{
if (HttpStatusCode.OK == rspFp.StatusCode)
{
Debug.WriteLine(string.Format("{0} - OK", strServer));
return true; // Dispose called when using is exited
}

// Include the error because it's nice to know these things
Debug.WriteLine(String.Format(
"{0} Server returned error: {1}",
strServer, rspFp.StatusCode));
return false;
}
}
catch (WebException x)
{
// Don't tempt fate and don't let programs read human-readable messages
if (x.Status == WebExceptionStatus.Timeout)
{
Debug.WriteLine(string.Format("{0} - Timed out", strServer));
}
else
{
// The FULL exception, please
Debug.WriteLine(x.ToString());
}

return false;
}
}

几乎完成 - 未测试深夜代码

public static void Main()
{
using (var conn = new SqlConnection())
{
conn.Open();
using (var cmd = new SqlCommand("", conn))
{
using (var rdr = cmd.ExecuteReader())
{
if (rdr == null)
{
return;
}

while (rdr.Read())
{
ThreadPool.QueueUserWorkItem(
CheckConnectionAvailable, rdr[0]);
}
}
}
}
}

private static void CheckConnectionAvailable(object weburl)
{
try
{
// If this works, it's a lot simpler
var strServer = new Uri("http://" + weburl);
using (var client = new WebClient())
{
client.UploadDataCompleted += ClientOnUploadDataCompleted;
client.UploadDataAsync(
strServer, "HEAD", new byte[] {}, strServer);
}
}
catch (WebException x)
{
Debug.WriteLine(x);
}
}

private static void ClientOnUploadDataCompleted(
object sender, UploadDataCompletedEventArgs args)
{
if (args.Error == null)
{
Debug.WriteLine(string.Format("{0} - OK", args.UserState));
}
else
{
Debug.WriteLine(string.Format("{0} - Error", args.Error));
}
}

关于c# - HttpWebRequest 限制?或者实现不当,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1123230/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com