如题,软件是一个读取文件的,里面有大量数据,文件数目量也比较大.将文件读取到datatable,然后绑定gridview进行显示.使用的backgroundWorker.
调试的时候怎么都正常.没有意外.
问题就在按ctrl+f5或者直接运行bin下面exe的时候,在文件数少的情况下正常,但是当读取大量文件时,到最后完成的时候,整个软件就死掉了(应该是在完成backgroundWorker_DoWork后几秒,因为读取文件是执行完了的,然后会死在调用完成函数backgroundWorker_RunWorkerCompleted的途中,注意是途中...但是这个函数并不执行什么复杂的,只是改变一下label,如果不使用RunWorkerCompleted函数,则会在完成后几秒软件莫名死掉)...代码没有什么特别的//按钮调用
private void Load_Button_Click(object sender, EventArgs e)
{
if (Directory.Exists(textBox_FilePath.Text) && (textBox_FilePath.Text != null))
{
backgroundWorker_load.RunWorkerAsync();
}
else
{
MessageBox.Show("Wrong folder path?");
}
}//DoWork函数
private void backgroundWorker_load_DoWork(object sender, DoWorkEventArgs e)
{
buttonenable(false);
load185.initdt();
string[] files = new string[256];
int count = 0;
PublicLoadFunc.GetFileList(textBox_FilePath.Text.Trim(), files, ref count);
if (files[0] == null)
{
MessageBox.Show("No file found.");
return;
}
for (int i = 0; i < count; i++)
{
backgroundWorker_load.ReportProgress((i * 100 + 50) / count,i.ToString()+"/"+count.ToString()+ " Loading " + files[i].ToString().Trim() + ".");
NewDelegate startLoad = new NewDelegate (load185.LoadOneFile);
startLoad.Invoke(files[i].ToString().Trim(), i);
//load185.LoadOneFile(files[i].ToString().Trim(), i);//这里用不用委托都一样
backgroundWorker_load.ReportProgress(((i + 1) * 100) / count, (i+1).ToString() + "/" + count.ToString() + " Loading " + files[i].ToString().Trim() + " completed.");
Application.DoEvents();
}
}完全想不明白了,也不知道怎么调试,弄了一天了哎,伤感...求高手指教
调试的时候怎么都正常.没有意外.
问题就在按ctrl+f5或者直接运行bin下面exe的时候,在文件数少的情况下正常,但是当读取大量文件时,到最后完成的时候,整个软件就死掉了(应该是在完成backgroundWorker_DoWork后几秒,因为读取文件是执行完了的,然后会死在调用完成函数backgroundWorker_RunWorkerCompleted的途中,注意是途中...但是这个函数并不执行什么复杂的,只是改变一下label,如果不使用RunWorkerCompleted函数,则会在完成后几秒软件莫名死掉)...代码没有什么特别的//按钮调用
private void Load_Button_Click(object sender, EventArgs e)
{
if (Directory.Exists(textBox_FilePath.Text) && (textBox_FilePath.Text != null))
{
backgroundWorker_load.RunWorkerAsync();
}
else
{
MessageBox.Show("Wrong folder path?");
}
}//DoWork函数
private void backgroundWorker_load_DoWork(object sender, DoWorkEventArgs e)
{
buttonenable(false);
load185.initdt();
string[] files = new string[256];
int count = 0;
PublicLoadFunc.GetFileList(textBox_FilePath.Text.Trim(), files, ref count);
if (files[0] == null)
{
MessageBox.Show("No file found.");
return;
}
for (int i = 0; i < count; i++)
{
backgroundWorker_load.ReportProgress((i * 100 + 50) / count,i.ToString()+"/"+count.ToString()+ " Loading " + files[i].ToString().Trim() + ".");
NewDelegate startLoad = new NewDelegate (load185.LoadOneFile);
startLoad.Invoke(files[i].ToString().Trim(), i);
//load185.LoadOneFile(files[i].ToString().Trim(), i);//这里用不用委托都一样
backgroundWorker_load.ReportProgress(((i + 1) * 100) / count, (i+1).ToString() + "/" + count.ToString() + " Loading " + files[i].ToString().Trim() + " completed.");
Application.DoEvents();
}
}完全想不明白了,也不知道怎么调试,弄了一天了哎,伤感...求高手指教
"注意确保在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信" 实在不行 你就用new Thread + delgate试试!就算操作20个G我也遇到过问题!
"注意确保在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信" 注意访问用户界面的方式!如果不行的话就用New Thread() + Delgate来做吧! 可能有助于你理解BackgroundWorker
谢谢~确实理解很浅,现在的代码看上去只有buttonenable和Application.DoEvents()跟界面有关,但是之前我根本就没加这2条在DoWork里面,我也都删掉试过,只留下逻辑相关的,还是会死,我明天试一下!非常感谢!
应该不是我backgroundworker的问题,虽然给出来的代码有些不对,但是出问题之前不是这么用的.怎么改都不行换之后发现是gridview的问题,还是老问题下拉条假死(这是公认的vs2005的bug么),但是好在程序没死,Application.DoEvents()也没用.
我想可能就是因为这个gridview的假死,导致backgroundworker出问题.
等等看有没人能帮忙解释或者解决下?
晚上结贴~谢谢大家!
http://msdn.microsoft.com/zh-cn/library/system.windows.forms.listview.virtualmode.aspx
http://www.cnblogs.com/hcfalan/archive/2008/07/08/1238493.html
http://www.cnblogs.com/easydata/archive/2008/07/02/1234161.html
因为我datatable的处理是在子线程里的,但是我为了能即时显示数据,程序一开始就绑定了datatable为gridview的数据源,而子线程的开始并没有使用this.invoke+委托而是直接用的委托开始的线程,这样也算导致了跨线程更新界面,之前的backgroundworker肯定也是因为这个数据源跨线程问题导致gridview滚动条假死进而整个程序死掉.
不知道我的分析有没有错误.
如果没错,就顺便提醒一下之前遇到gridview滚动条假死无效的朋友们,应该都是和我类似的问题了,就是要用this.invoke+委托来处理gridview的数据源.