创建新行并从小型 CSV 文件添加到数据表时出现 OOM 异常
OOM Exception while creating newRows and adding to datatable from a small CSV file
下面的代码登录到一个 https 网站,抓取一个 cookie,然后导航到另一个页面以下载一个 CSV 文件作为字符串。然后将该字符串拆分为一个数组,用于创建要添加到数据表的数据行。一切正常,直到 populateTable 方法中的循环抛出内存不足异常。 CSV 文件只有 206 KB,包含大约 500 行,包含拆分 CSV 字符串的数组包含 16,206 个字符串。在 Windows 7 中查看资源监视器,我可以看到程序在崩溃前缓慢地将其 RAM 大小增加到 ~1.2 GB。
很遗憾,我无法共享网站 URL。
我并不是真的在寻求解决问题的帮助,而是想知道为什么会出现这种情况,因为 CSV 文件不是那么大。有输入吗?
namespace GetSCInfo
{
public partial class Form1 : Form
{
DataTable dt = new DataTable("clientInfo");
public Form1()
{
InitializeComponent();
createTable();
}
private void button1_Click(object sender, EventArgs e)
{
DateTime today = DateTime.Today;
//Starting date for the query. the 2f is required
string startDate = "01%2f01%2f2005";
string endDate = today.Month.ToString() + "%" + today.Day.ToString() + "%" + today.Year.ToString();
//Check the date to make sure 2 digits are used for the month and day. If only one is used then add a 0.
string[] dateFormat = endDate.Split('%');
if (dateFormat[0].Length < 2)
dateFormat[0] = "0" + dateFormat[0];
if (dateFormat[1].Length < 2)
dateFormat[1] = "0" + dateFormat[1];
endDate = dateFormat[0] + "%2f" + dateFormat[1] + "%2f" + dateFormat[2];
//Values for the form on the website
using (var client = new CookieAwareWebClient())
{
var values = new NameValueCollection
{
{"eid", ""},
{"EmailAddress", "example@example.com"},
{"Password", "myPassword"},
{"chk_NotificationOnly", "false"},
{"btn_login", "Login"},
};
//Login and get the cookie
client.UploadValues("https://Website/loginpage", values);
// If the previous call succeeded we now have a valid authentication cookie
// so we could download the protected page
var val2 = new NameValueCollection
{
{"StartDate", startDate},
{"EndDate", endDate},
{"ReportFormat", "CSV"},
};
string bytes = client.DownloadString("https://website/csvPage?StartDate=" + startDate + "&EndDate=" + endDate + "&ReportFormat=CSV");
client.Dispose();
populateTable(bytes);
}
}
private void createTable()
{
dt.Columns.Add("Assists ID", typeof(string));
dt.Columns.Add("Last Name", typeof(string));
dt.Columns.Add("First Name", typeof(string));
dt.Columns.Add("S/C Name", typeof(string));
dt.Columns.Add("S/C Phone", typeof(string));
dt.Columns.Add("S/C Email", typeof(string));
}
private void populateTable(string data)
{
dt.Clear();
string[] csvValues = data.Split(',');
data = "";
for(int i = 19; i < csvValues.Length - 19; i=+19)
{
DataRow row = dt.NewRow();
row[0] = csvValues[i];
row[1] = csvValues[i + 1];
row[2] = csvValues[i + 2];
row[3] = csvValues[i + 14];
row[4] = csvValues[i + 15];
row[5] = csvValues[i + 16];
dt.Rows.Add(row);
//dt.Rows.Add(csvValues[i], csvValues[i+1], csvValues[i+2], csvValues[i+14], csvValues[i+15], csvValues[i+16]);
}
dataGridView1.DataSource = dt;
}
}
//Extend the Webclient
public class CookieAwareWebClient : WebClient
{
private readonly CookieContainer m_container = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
HttpWebRequest webRequest = request as HttpWebRequest;
if (webRequest != null)
{
webRequest.CookieContainer = m_container;
}
return request;
}
}
}
你会踢自己的。在 populateTable
中,for
循环增量没有递增。你有 i=+19
而不是 i+=19
。您只是将 i
设置为 19,然后一遍又一遍地创建新的 DataRow
。
下面的代码登录到一个 https 网站,抓取一个 cookie,然后导航到另一个页面以下载一个 CSV 文件作为字符串。然后将该字符串拆分为一个数组,用于创建要添加到数据表的数据行。一切正常,直到 populateTable 方法中的循环抛出内存不足异常。 CSV 文件只有 206 KB,包含大约 500 行,包含拆分 CSV 字符串的数组包含 16,206 个字符串。在 Windows 7 中查看资源监视器,我可以看到程序在崩溃前缓慢地将其 RAM 大小增加到 ~1.2 GB。
很遗憾,我无法共享网站 URL。
我并不是真的在寻求解决问题的帮助,而是想知道为什么会出现这种情况,因为 CSV 文件不是那么大。有输入吗?
namespace GetSCInfo
{
public partial class Form1 : Form
{
DataTable dt = new DataTable("clientInfo");
public Form1()
{
InitializeComponent();
createTable();
}
private void button1_Click(object sender, EventArgs e)
{
DateTime today = DateTime.Today;
//Starting date for the query. the 2f is required
string startDate = "01%2f01%2f2005";
string endDate = today.Month.ToString() + "%" + today.Day.ToString() + "%" + today.Year.ToString();
//Check the date to make sure 2 digits are used for the month and day. If only one is used then add a 0.
string[] dateFormat = endDate.Split('%');
if (dateFormat[0].Length < 2)
dateFormat[0] = "0" + dateFormat[0];
if (dateFormat[1].Length < 2)
dateFormat[1] = "0" + dateFormat[1];
endDate = dateFormat[0] + "%2f" + dateFormat[1] + "%2f" + dateFormat[2];
//Values for the form on the website
using (var client = new CookieAwareWebClient())
{
var values = new NameValueCollection
{
{"eid", ""},
{"EmailAddress", "example@example.com"},
{"Password", "myPassword"},
{"chk_NotificationOnly", "false"},
{"btn_login", "Login"},
};
//Login and get the cookie
client.UploadValues("https://Website/loginpage", values);
// If the previous call succeeded we now have a valid authentication cookie
// so we could download the protected page
var val2 = new NameValueCollection
{
{"StartDate", startDate},
{"EndDate", endDate},
{"ReportFormat", "CSV"},
};
string bytes = client.DownloadString("https://website/csvPage?StartDate=" + startDate + "&EndDate=" + endDate + "&ReportFormat=CSV");
client.Dispose();
populateTable(bytes);
}
}
private void createTable()
{
dt.Columns.Add("Assists ID", typeof(string));
dt.Columns.Add("Last Name", typeof(string));
dt.Columns.Add("First Name", typeof(string));
dt.Columns.Add("S/C Name", typeof(string));
dt.Columns.Add("S/C Phone", typeof(string));
dt.Columns.Add("S/C Email", typeof(string));
}
private void populateTable(string data)
{
dt.Clear();
string[] csvValues = data.Split(',');
data = "";
for(int i = 19; i < csvValues.Length - 19; i=+19)
{
DataRow row = dt.NewRow();
row[0] = csvValues[i];
row[1] = csvValues[i + 1];
row[2] = csvValues[i + 2];
row[3] = csvValues[i + 14];
row[4] = csvValues[i + 15];
row[5] = csvValues[i + 16];
dt.Rows.Add(row);
//dt.Rows.Add(csvValues[i], csvValues[i+1], csvValues[i+2], csvValues[i+14], csvValues[i+15], csvValues[i+16]);
}
dataGridView1.DataSource = dt;
}
}
//Extend the Webclient
public class CookieAwareWebClient : WebClient
{
private readonly CookieContainer m_container = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
HttpWebRequest webRequest = request as HttpWebRequest;
if (webRequest != null)
{
webRequest.CookieContainer = m_container;
}
return request;
}
}
}
你会踢自己的。在 populateTable
中,for
循环增量没有递增。你有 i=+19
而不是 i+=19
。您只是将 i
设置为 19,然后一遍又一遍地创建新的 DataRow
。