当试图读取和解码大文件时,C#GUI会冻结
我开发了一个GUI winforms来读取和解码CSV文件,并将其保存为Excel和CSV格式。我正在datagridview中显示解码的数据。一切都很好,但由于一些奇怪的原因,GUI被冻结了,因为文件太大,或者这里的天气很冷。它仍然做它想做的事情,但显示(软件没有响应)。我也使用了线程和背景工作,但仍然没有希望。这是代码。请分享任何帮助当试图读取和解码大文件时,C#GUI会冻结,c#,winforms,csv,datagridview,C#,Winforms,Csv,Datagridview,我开发了一个GUI winforms来读取和解码CSV文件,并将其保存为Excel和CSV格式。我正在datagridview中显示解码的数据。一切都很好,但由于一些奇怪的原因,GUI被冻结了,因为文件太大,或者这里的天气很冷。它仍然做它想做的事情,但显示(软件没有响应)。我也使用了线程和背景工作,但仍然没有希望。这是代码。请分享任何帮助 public delegate void UpdatingTable(); private void backgroundWorker1_DoWor
public delegate void UpdatingTable();
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Invoke(new UpdatingTable(DecodingData));
}
private void cnvrtB_Click(object sender, EventArgs e)
{
progressBar1.Enabled = true;
progressBar1.Visible = true;
saveB.Visible = true;
cnvrtB.Enabled = false;
label5.Visible = true;
backgroundWorker1.RunWorkerAsync();
//DecodingThread = new Thread(new ThreadStart(StartDecoding));
//DecodingThread.IsBackground = true;
//if (!(DecodingThread.IsAlive) || DecodingThread == null)
//{
// progressBar1.Enabled = true;
// progressBar1.Visible = true;
// saveB.Visible = true;
// cnvrtB.Enabled = false;
// label5.Visible = true;
// Thread.Sleep(2000);
// DecodingThread.Start();
//}
//else if (DecodingThread.IsAlive)
//{
// progressBar1.Enabled = true;
// progressBar1.Visible = true;
// saveB.Visible = true;
// cnvrtB.Enabled = false;
// label5.Visible = true;
// DecodingThread.Resume();
//}
}
private void StartDecoding()
{
Thread.Sleep(1000);
Invoke(new UpdatingTable(DecodingData));
}
public void DecodingData()
{
try
{
//delete old records
records.Clear();
//get records from converter
if (VersionNumber == 1)
{
records.AddRange(LogEventDecode.getRecords());
}
else if (VersionNumber == 0)
{
records.AddRange(LogEventDecode.getRecordsOld());
}
//create datatable for records
table = new System.Data.DataTable("data");
//create columns
table.Columns.Add("Time", typeof(System.DateTime));
table.Columns.Add("Date", typeof(System.DateTime));
table.Columns.Add("dt", typeof(System.DateTime));
table.Columns.Add("User", typeof(System.String));
table.Columns.Add("SourceInformation", typeof(System.String));
table.Columns.Add("SourceType", typeof(System.String));
table.Columns.Add("SourceCondition", typeof(System.String));
table.Columns.Add("securityLevel", typeof(System.String));
table.Columns.Add("AdditionalInformation", typeof(System.String));
table.Columns.Add("RubCondition", typeof(System.String));
//populate datatable
foreach (LogRecord r in records)
{
DataRow row = table.NewRow();
row["Time"] = r.Time;
row["Date"] = r.Date;
row["dt"] = r.dt;
row["User"] = r.User;
row["SourceInformation"] = r.SourceInformation;
row["SourceType"] = r.SourceType;
row["SourceCondition"] = r.SourceCondition;
row["securityLevel"] = r.SecurityLevel;
row["AdditionalInformation"] = r.AdditionalInformation;
row["RubCondition"] = r.RubCondition;
table.Rows.Add(row);
//DecodingCount++;
//label5.Text = "Decoded" + DecodingCount + " out of Total Logs " + records.Count;
}
view = new DataView(table);
//bind to grid
//DecodingThread.Abort();
}
catch
{
MessageB.Show("Please make sure you have Imported the File \nOR\n The imported file is not corrupted.", "File Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
cnvrtB.Enabled = true;
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
logRecordBindingSource.DataSource = view;
cnvrtB.Enabled = true;
progressBar1.Visible = false;
progressBar1.Enabled = false;
label5.Visible = false;
}
给定的示例显示了线程和后台方法
感谢您在后台工作人员中不要调用
Invoke
,以下是Invoke
的功能:
在拥有控件底层窗口句柄的线程上执行委托
因此,您的后台工作程序正在控件(即GUI)线程上执行代码,如下所示,
Invoke
在您的后台工作程序中不调用Invoke
:
在拥有控件底层窗口句柄的线程上执行委托
因此,您的后台工作人员正在控件(即GUI)线程上执行代码从何处调用StartDecoding?如果从UI线程调用,它的睡眠将冻结UI为什么在后台工作程序中调用
Invoke
?调用Invoke更新表从何处调用StartDecoding?如果从UI线程调用,它的睡眠将冻结UI为什么在后台工作程序中调用Invoke
?调用Invoke更新表格谢谢你的回答,但是我如何使用代理以及如何防止GUI冻结。。请回答这个愚蠢的问题不确定我是否理解您的问题-您可以在backgroundWorker1\u-DoWork
中调用decodingdata
,然后在读取完成后处理后台工作人员的RunWorkerCompleted
事件以更新GUI。。这回答了你的问题吗?谢谢,这就是我的想法。希望它能起作用。谢谢@KMoussaDid您检查一下,应用程序在什么时候冻结?因为当UI开始将DataView绑定到网格时,它可能会被冻结,这是一个漫长的过程。您可以尝试使用这个绑定调用来开始/endUpdateAnks以获得答案,但是我如何使用委托以及它如何防止GUI冻结。。请回答这个愚蠢的问题不确定我是否理解您的问题-您可以在backgroundWorker1\u-DoWork
中调用decodingdata
,然后在读取完成后处理后台工作人员的RunWorkerCompleted
事件以更新GUI。。这回答了你的问题吗?谢谢,这就是我的想法。希望它能起作用。谢谢@KMoussaDid您检查一下,应用程序在什么时候冻结?因为当UI开始将DataView绑定到网格时,它可能会被冻结,这是一个漫长的过程。您可以尝试使用此绑定调用来开始/结束更新