我是C#的新手,我正在使用windows forms
。
我正在构建一个应用程序,当Form
加载时,我遇到了一个奇怪的严重问题。
我有2 forms
:
Form1
有button_Edit
和DataGridView
Form2
有DataGridView1
和DataGridView2
正如代码和屏幕截图中显示的那样,当我在Form1
中选择一行时,在DataGridView
中,然后点击Button_Edit
Order number
和{{1} } DateTime
上的DataGridView
中的值传递给Form1
,然后Form2
打开。
现在在Form2
Form2
中有一个Load event
查询,需要SQL
和Order number
来提供相关的订单详细信息,然后填写DateTime
和{ {1}}中的{1}}。
在Form1中:
DataGridView1
在Form2中:
DataGridView2
问题:
此代码可以正常工作,正如我所希望的那样Form2
& Form2 frm2 = new Form2();
private void button_Edit_Click(object sender, EventArgs e)
{
frm2._ Order_Number= Convert.ToInt32(dataGridView1.SelectedRows[0].Cells[0].Value);
frm2._ Date_Time= Convert.ToDateTime(dataGridView1.SelectedRows[0].Cells[4].Value);
frm2.ShowDialog();
}
中的 SqlConnection MyConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
SqlCommand MyCommand = new SqlCommand();
DataTable DataTable = new DataTable();
SqlDataAdapter Sql_Data_Adapter = new SqlDataAdapter();
int Order_Number;
DateTime Date_Time;
int i;
double Sum;
int RowIndex;
public int _ Order_Number
{
set { Order_Number = value; }
}
public DateTime _ Date_Time
{
set { Date_Time = value; }
}
private void Form2_Load(object sender, EventArgs e)
{
DataTable.Rows.Clear();
DataTable.Columns.Clear();
MyConnection.Open();
MyCommand.CommandText = "SELECT * FROM Customer_Order_Details WHERE Order_Number = @OrderNumber and Date_Time = @DateTime ";
MyCommand.Connection = MyConnection;
MyCommand.Parameters.Add("@OrderNumber", SqlDbType.Int).Value = Order_Number;
MyCommand.Parameters.Add("@DateTime", SqlDbType.DateTime).Value = Date_Time;
Sql_Data_Adapter.SelectCommand = MyCommand;
Sql_Data_Adapter.Fill(DataTable);
MyCommand.Parameters.Clear();
MyConnection.Close();
dataGridView1.Rows.Clear();
dataGridView2.Rows[0].Cells[1].Value = 0;
Sum = 0;
//////////////FILL THE ORDER INTO DATAGRIDVIEW1///////////
RowIndex = DataTable.Rows.Count - 1;
for (i = 0; i <= RowIndex; i++)
{
dataGridView1.Rows.Add(DataTable.Rows[i][2], DataTable.Rows[i][3], DataTable.Rows[i][4]);
// Calculate the total:
Sum = Convert.ToDouble(DataTable.Rows[i][4]) + Sum;
}
dataGridView2.Rows[0].Cells[1].Value = sum;
}
填充了正确的详细信息,并且在DataGridView1
加载时工作正常。
但是,在填写DataGridView2
和{}之后,有时会Form2
冻结加载Form2
时Form2
,在使用任务管理器终止应用程序之前,我无法执行任何操作。
这个问题有时会发生,而且是不可预测的。我真的不知道出了什么问题。
我看了here,here和here,但没有与我的问题相关的问题。请注意,我已经使用了try catch,它不会抛出任何东西,因为表单会冻结。这种冻结行为发生在发布模式中,我的意思是在我构建EXE文件然后我将其安装在PC中,这里出现了问题。
有谁知道为什么会出现这种糟糕的不可预测行为? 我的代码中有什么我应该改变的吗? 我会很高兴听到任何新的想法/解决方案,无论它有多小,它都会非常有益。 谢谢
答案 0 :(得分:2)
SQL是否适用于另一个线程。检查异步调用。
答案 1 :(得分:1)
我建议使用Async
Open
版本(连接到RDBMS)和ExecuteReader
(查询执行):
con.Open() -> await con.OpenAsync()
q.ExecuteReader() -> await q.ExecuteReaderAsync()
这种简单的替换使得UI 负责(它不会冻结),同时连接到RDBMS并执行查询。
// do not forget to mark Form2_Load method as async
private async void Form2_Load(object sender, EventArgs e) {
// Do not share the connection - create it and dispose for each call
using (SqlConnection con = new SqlConnection(...)) {
await con.OpenAsync();
string sql =
@"SELECT *
FROM Customer_Order_Details
WHERE Order_Number = @OrderNumber
AND Date_Time = @DateTime";
// do not share command/query as well
using (SqlCommand q = new SqlCommand(sql, con)) {
q.Parameters.Add("@OrderNumber", SqlDbType.Int).Value = Order_Number;
q.Parameters.Add("@DateTime", SqlDbType.DateTime).Value = Date_Time;
dataGridView1.Rows.Clear();
dataGridView2.Rows[0].Cells[1].Value = 0;
Sum = 0;
// We actually don't want any sql adapter:
// all we have to do is to fetach data from cursor and append it to grids
using (var reader = await q.ExecuteReaderAsync()) {
while (reader.Read()) {
dataGridView1.Rows.Add(reader[2], reader[3], reader[4]);
Sum += Convert.ToDouble(reader[4]);
}
}
}
}
}
答案 2 :(得分:1)
如上所述,你给我们的代码片段写得不好。您应该使用更多的Try / Catch语句来防止程序崩溃和冻结。这将帮助您在发布时运行Programm时查找错误。此外,您有很多选择来解决您的问题。
1: 尝试在第二个线程中启动Form2,然后只有你的form2将冻结,直到你的sql完成
2: 如前所述,尝试使用异步调用来避免处理sql的冻结时间
3: 没有直接需要SQL数据库/连接。您还可以使用Collection并创建您的Products定义的对象(如cola),然后通过数据库绑定它们。 (如果你有兴趣,我可以给你看一个例子)
最好的方法是:
添加一些Try / Catch语句并熟悉它,熟悉Systems.Thread并尝试在新线程中启动form2,如果这项工作转到第2步并添加asynchronus调用
最后,我想告诉你,那个名字就是你的表格&#34; Form1&#34;和&#34; Form2&#34;不太好,也许你想改变它。