C#错误的http响应
我有一个线程返回站点的http响应状态,但有时我的程序返回错误的结果。一段时间后,它会产生良好的效果。C#错误的http响应,c#,httpresponse,C#,Httpresponse,我有一个线程返回站点的http响应状态,但有时我的程序返回错误的结果。一段时间后,它会产生良好的效果。 错误结果: 检查需要花费大量的时间,然后它说(例如)谷歌宕机了,这是不合理的,但几秒钟后它返回了良好的结果 你能看一下并告诉我怎么了吗?或者我可以如何改进它? 检查datagrid中的所有站点: private void CheckSites() { if (CheckSelected()) {
错误结果: 检查需要花费大量的时间,然后它说(例如)谷歌宕机了,这是不合理的,但几秒钟后它返回了良好的结果 你能看一下并告诉我怎么了吗?或者我可以如何改进它?
检查datagrid中的所有站点:
private void CheckSites()
{
if (CheckSelected())
{
int rowCount = dataGrid.BindingContext[dataGrid.DataSource, dataGrid.DataMember].Count;
string url;
for (int i = 0; i < rowCount; i++)
{
url = dataGrid.Rows[i].Cells[2].Value.ToString();
if (url != null)
{
Task<string[]> task = Task.Factory.StartNew<string[]>
(() => checkSite(url));
// We can do other work here and it will execute in parallel:
//Loading...
// When we need the task's return value, we query its Result property:
// If it's still executing, the current thread will now block (wait)
// until the task finishes:
string[] result = task.Result;
selectRows();
if (result[0] != System.Net.HttpStatusCode.OK.ToString() && result[0] != System.Net.HttpStatusCode.Found.ToString() && result[0] != System.Net.HttpStatusCode.MovedPermanently.ToString())
{
//bad
notifyIcon1.ShowBalloonTip(5000, "Site Down", dataGrid.Rows[i].Cells[2].Value.ToString() + ", has a status code of:" + result, ToolTipIcon.Error);
dataGrid.Rows[i].DefaultCellStyle.BackColor = System.Drawing.Color.Wheat;
TimeSpan ts;
TimeSpan timeTaken = TimeSpan.Parse(result[1]);
dataGrid.Rows[i].Cells[3].Value = result[0];
dataGrid.Rows[i].Cells[3].Style.BackColor = System.Drawing.Color.Red;
dataGrid.Rows[i].Cells[4].Value = timeTaken.Seconds.ToString() + "." + String.Format("{0:0.00000}", timeTaken.Milliseconds.ToString()) + " seconds.";
string sec = (DateTime.Now.Second < 10) ? "0" + DateTime.Now.Second.ToString() : DateTime.Now.Second.ToString();
string min = (DateTime.Now.Minute < 10) ? "0" + DateTime.Now.Minute.ToString() : DateTime.Now.Minute.ToString();
string hour = (DateTime.Now.Hour < 10) ? "0" + DateTime.Now.Hour.ToString() : DateTime.Now.Hour.ToString();
dataGrid.Rows[i].Cells[5].Value = hour + ":" + min + ":" + sec;
//loadbar
}
else if (result[0] == "catch")//catch
{
notifyIcon1.ShowBalloonTip(10000, "SITE DOWN", dataGrid.Rows[i].Cells[1].Value.ToString() + ", Error:" +result[1], ToolTipIcon.Error);
dataGrid.Rows[i].Cells[3].Value = result[1];
dataGrid.Rows[i].Cells[3].Style.BackColor = System.Drawing.Color.Red;
//loadbar
}
else
{
//good
TimeSpan timeTaken = TimeSpan.Parse(result[1]);
dataGrid.Rows[i].Cells[3].Value = result[0];
dataGrid.Rows[i].Cells[3].Style.BackColor = System.Drawing.Color.LightGreen;
dataGrid.Rows[i].Cells[4].Value = timeTaken.Seconds.ToString() + "." + String.Format("{0:0.00000}", timeTaken.Milliseconds.ToString()) + " seconds.";
string sec = (DateTime.Now.Second < 10) ? "0" + DateTime.Now.Second.ToString() : DateTime.Now.Second.ToString();
string min = (DateTime.Now.Minute < 10) ? "0" + DateTime.Now.Minute.ToString() : DateTime.Now.Minute.ToString();
string hour = (DateTime.Now.Hour < 10) ? "0" + DateTime.Now.Hour.ToString() : DateTime.Now.Hour.ToString();
dataGrid.Rows[i].Cells[5].Value = hour + ":" + min + ":" + sec;
//loadbar
}
selectRows();
}
}
}
}
/////////////////////////////////
////Check datagrid websites-button - returns response
/////////////////////////////////
private string[] checkSite(string url)
{
string[] response = new string[2];
url = dataGrid.Rows[0].Cells[2].Value.ToString();
if (url != null)
{
try
{
HttpWebRequest httpReq;
httpReq.Timeout = 10000;
//loadbar
dataGrid.Rows[0].DefaultCellStyle.BackColor = System.Drawing.Color.Wheat;
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
timer.Start();
HttpWebResponse httpRes = (HttpWebResponse)httpReq.GetResponse(); //httpRes.Close();
timer.Stop();
//loadbar
HttpStatusCode httpStatus = httpRes.StatusCode;
response[0] = httpStatus.ToString();
response[1] = timer.Elapsed.ToString();//*
httpRes.Close();
return response;
}
catch (Exception he)
{
response[0] = "catch";
response[1] = he.Message;
return response;
}
}
response[0] = "catch";
response[1] = "No URL entered";
return response;
//dataGrid.Rows[i].DefaultCellStyle.BackColor = System.Drawing.Color.Blue;
}
提前感谢。为了模拟您的场景,我创建了一个带有数据网格和按钮的Winform。加载表单时,我以编程方式创建url列表(在表中)并绑定到数据网格。点击按钮,我们开始下载过程。简而言之,您必须编写更多的防御性代码,下面的代码只是解决问题的框架
using System;
using System.Data;
using System.Net;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace app
{
public partial class Form1 : Form
{
DataTable urls = new DataTable();
public Form1()
{
InitializeComponent();
}
//Fill your uri's and bind to a data grid.
void InitTable()
{
//Silly logic to simulate your scenario.
urls = new DataTable();
urls.Columns.Add(new DataColumn("Srl", typeof(string)));
urls.Columns.Add(new DataColumn("Urls", typeof(Uri)));
urls.Columns.Add(new DataColumn("Result", typeof(string)));
DataRow dr = urls.NewRow();
dr["Srl"] = "1";
dr["Urls"] = new Uri("http://www.microsoft.com");
dr["Result"] = string.Empty;
urls.Rows.Add(dr);
dr = urls.NewRow();
dr["Srl"] = "2";
dr["Urls"] = new Uri("http://www.google.com");
dr["Result"] = string.Empty;
urls.Rows.Add(dr);
dr = urls.NewRow();
dr["Srl"] = "3";
dr["Urls"] = new Uri("http://www.stackoverflow.com");
dr["Result"] = string.Empty;
urls.Rows.Add(dr);
urls.AcceptChanges();
}
void UpdateResult()
{
dataGridView1.DataSource = urls;
}
//Important
// This example will freeze UI. You can avoid this while implementing
//background worker or pool with some event synchronization. I haven't covered those area since
//we are addressing different issue. Let me know if you would like to address UI freeze
//issue. Or can do it your self.
private void button1_Click(object sender, EventArgs e)
{
//Create array for Task to parallelize multiple download.
var tasks = new Task<string[]>[urls.Rows.Count];
//Initialize those task based on number of Uri's
for(int i=0;i<urls.Rows.Count;i++)
{
int index = i;//Do not change this. This is to avoid data race
//Assign responsibility and start task.
tasks[index] = new Task<string[]>(
() => checkSite(
new TaskInput(urls.Rows[index]["Urls"].ToString(), urls.Rows[index]["Srl"].ToString())));
tasks[index].Start();
}
//Wait for all task to complete. Check other overloaded if interested.
Task.WaitAll(tasks);
//block shows how to access result from task
foreach (var item in tasks)
{
DataRow[] rows=urls.Select("Srl='"+item.Result[2]+"'");
foreach (var row in rows)
row["Result"]=item.Result[0]+"|"+item.Result[1];
}
UpdateResult();
}
//This is dummy method which in your case 'Check Site'. You can have your own
string[] checkSite(TaskInput input)
{
string[] response = new string[3];
if (input != null)
{
try
{
WebResponse wResponse = WebRequest.Create(input.Url).GetResponse();
response[0] = wResponse.ContentLength.ToString();
response[1] = wResponse.ContentType;
response[2] = input.Srl;
return response;
}
catch (Exception he)
{
response[0] = "catch";
response[1] = he.Message;
response[2] = input.Srl;
return response;
}
}
response[0] = "catch";
response[1] = "No URL entered";
response[2] = input.Srl;
return response;
}
private void Form1_Load(object sender, EventArgs e)
{
InitTable();
UpdateResult();
}
}
//Supply custom object for simplicity
public class TaskInput
{
public TaskInput(){}
public TaskInput(string url, string srl)
{
Url = url;
Srl = srl;
}
public string Srl { get; set; }
public string Url { get; set; }
}
}
使用系统;
使用系统数据;
Net系统;
使用System.Threading.Tasks;
使用System.Windows.Forms;
命名空间应用程序
{
公共部分类Form1:Form
{
DataTable URL=新DataTable();
公共表格1()
{
初始化组件();
}
//填充uri并绑定到数据网格。
void InitTable()
{
//用愚蠢的逻辑来模拟你的场景。
URL=新数据表();
添加(新数据列(“Srl”,typeof(string));
添加(新的数据列(“URL”,typeof(Uri));
Add(新数据列(“结果”,typeof(字符串));
DataRow dr=url.NewRow();
dr[“Srl”]=“1”;
dr[“URL”]=新Uri(“http://www.microsoft.com");
dr[“Result”]=string.Empty;
url.Rows.Add(dr);
dr=url.NewRow();
dr[“Srl”]=“2”;
dr[“URL”]=新Uri(“http://www.google.com");
dr[“Result”]=string.Empty;
url.Rows.Add(dr);
dr=url.NewRow();
dr[“Srl”]=“3”;
dr[“URL”]=新Uri(“http://www.stackoverflow.com");
dr[“Result”]=string.Empty;
url.Rows.Add(dr);
AcceptChanges();
}
void UpdateResult()
{
dataGridView1.DataSource=URL;
}
//重要的
//此示例将冻结UI。您可以在实现时避免此情况
//有一些事件同步的后台工作者或池。从那以后我就没有涉及过这些领域
//我们正在解决不同的问题。如果您想解决UI冻结问题,请告诉我
//问题。或者你可以自己做。
私有无效按钮1\u单击(对象发送者,事件参数e)
{
//为任务创建阵列以并行化多个下载。
var tasks=新任务[url.Rows.Count];
//根据Uri的数量初始化这些任务
对于(int i=0;i检查站点(
新任务输入(url.Rows[index][“url”].ToString(),url.Rows[index][“Srl”].ToString());
任务[index].Start();
}
//等待所有任务完成。如果感兴趣,请检查其他任务。
Task.WaitAll(任务);
//块显示如何从任务访问结果
foreach(任务中的变量项)
{
DataRow[]rows=url.Select(“Srl=”+项.Result[2]+”);
foreach(行中的变量行)
行[“结果”]=项.Result[0]+“|”+项.Result[1];
}
UpdateResult();
}
//这是一种虚拟方法,在你的例子中是“检查站点”。你可以有自己的方法
字符串[]检查站点(TaskInput)
{
字符串[]响应=新字符串[3];
如果(输入!=null)
{
尝试
{
WebResponse wResponse=WebRequest.Create(input.Url).GetResponse();
响应[0]=wResponse.ContentLength.ToString();
响应[1]=wResponse.ContentType;
响应[2]=input.Srl;
返回响应;
}
抓住(他例外)
{
响应[0]=“捕获”;
响应[1]=he.Message;
响应[2]=input.Srl;
返回响应;
}
}
响应[0]=“捕获”;
响应[1]=“未输入URL”;
响应[2]=input.Srl;
返回响应;
}
私有void Form1\u加载(对象发送方、事件参数e)
{
InitTable();
UpdateResult();
}
}
//提供自定义对象以简化操作
公共类任务输入
{
公共任务输入(){}
公共任务输入(字符串url、字符串srl)
{
Url=Url;
Srl=Srl;
}
公共字符串Srl{get;set;}
公共字符串Url{get;set;}
}
}
为了模拟您的场景,我创建了一个带有数据网格和按钮的Winform。加载表单时,我以编程方式创建url列表(在表中)并绑定到数据网格。点击按钮,我们开始下载过程。简而言之,您必须编写更多的防御性代码,下面的代码只是解决问题的框架
using System;
using System.Data;
using System.Net;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace app
{
public partial class Form1 : Form
{
DataTable urls = new DataTable();
public Form1()
{
InitializeComponent();
}
//Fill your uri's and bind to a data grid.
void InitTable()
{
//Silly logic to simulate your scenario.
urls = new DataTable();
urls.Columns.Add(new DataColumn("Srl", typeof(string)));
urls.Columns.Add(new DataColumn("Urls", typeof(Uri)));
urls.Columns.Add(new DataColumn("Result", typeof(string)));
DataRow dr = urls.NewRow();
dr["Srl"] = "1";
dr["Urls"] = new Uri("http://www.microsoft.com");
dr["Result"] = string.Empty;
urls.Rows.Add(dr);
dr = urls.NewRow();
dr["Srl"] = "2";
dr["Urls"] = new Uri("http://www.google.com");
dr["Result"] = string.Empty;
urls.Rows.Add(dr);
dr = urls.NewRow();
dr["Srl"] = "3";
dr["Urls"] = new Uri("http://www.stackoverflow.com");
dr["Result"] = string.Empty;
urls.Rows.Add(dr);
urls.AcceptChanges();
}
void UpdateResult()
{
dataGridView1.DataSource = urls;
}
//Important
// This example will freeze UI. You can avoid this while implementing
//background worker or pool with some event synchronization. I haven't covered those area since
//we are addressing different issue. Let me know if you would like to address UI freeze
//issue. Or can do it your self.
private void button1_Click(object sender, EventArgs e)
{
//Create array for Task to parallelize multiple download.
var tasks = new Task<string[]>[urls.Rows.Count];
//Initialize those task based on number of Uri's
for(int i=0;i<urls.Rows.Count;i++)
{
int index = i;//Do not change this. This is to avoid data race
//Assign responsibility and start task.
tasks[index] = new Task<string[]>(
() => checkSite(
new TaskInput(urls.Rows[index]["Urls"].ToString(), urls.Rows[index]["Srl"].ToString())));
tasks[index].Start();
}
//Wait for all task to complete. Check other overloaded if interested.
Task.WaitAll(tasks);
//block shows how to access result from task
foreach (var item in tasks)
{
DataRow[] rows=urls.Select("Srl='"+item.Result[2]+"'");
foreach (var row in rows)
row["Result"]=item.Result[0]+"|"+item.Result[1];
}
UpdateResult();
}
//This is dummy method which in your case 'Check Site'. You can have your own
string[] checkSite(TaskInput input)
{
string[] response = new string[3];
if (input != null)
{
try
{
WebResponse wResponse = WebRequest.Create(input.Url).GetResponse();
response[0] = wResponse.ContentLength.ToString();
response[1] = wResponse.ContentType;
response[2] = input.Srl;
return response;
}
catch (Exception he)
{
response[0] = "catch";
response[1] = he.Message;
response[2] = input.Srl;
return response;
}
}
response[0] = "catch";
response[1] = "No URL entered";
response[2] = input.Srl;
return response;
}
private void Form1_Load(object sender, EventArgs e)
{
InitTable();
UpdateResult();
}
}
//Supply custom object for simplicity
public class TaskInput
{
public TaskInput(){}
public TaskInput(string url, string srl)
{
Url = url;
Srl = srl;
}
public string Srl { get; set; }
public string Url { get; set; }
}
}
使用系统;
使用系统数据;
Net系统;
使用System.Threading.Tasks;
使用System.Windows.Forms;
命名空间应用程序
{
公共部分类Form1:Form
{
DataTable URL=新DataTable();
公共表格1()
{
初始化组件();
}
//填充uri并绑定到数据网格。
void InitTable()
{
//用愚蠢的逻辑来模拟你的场景。
URL=新数据表();
添加(新数据列(“Srl”,typeof(string));
添加(新数据列(“URL”),ty