我有一个程序可以对数百万条记录进行彻底的计算。有时,它运行超过一个小时,有时约30分钟。在此期间,程序没有响应或无法点击。这有什么解决方法吗?比如,加载鼠标图标。
另一个问题是,如果我将两个字典作为datagrid的数据源,那么与读取csv文件并将其放入datagrid相比,它会非常慢。这是算法:
for i = 0 to last record
datarow row = new datarow
put i to row[0]
put names[i] to row[1]
put comments[i] to row[2]
add row to datatable
end for loop
datatable.acceptchanges()
datagridview.datasource = datatable
注意:names [i]和comments [i]是字典。但是,如果我只是从具有几乎相同循环的csv文件中读取并将其放入datatable并将其作为datagridview的数据源,则它更快(与20分钟的词典相比,大约5-10分钟)。有没有解决办法?
答案 0 :(得分:3)
您所要做的就是使用一些多线程来在UI线程以外的线程上执行长时间运行的进程:
var task = new Task(() =>
{
// do some work to get your dataTable
dataTable.AcceptChanges();
datagridview
.Invoke(new Action(() => datagridview.DataSource = dataTable));
});
task.Start();
答案 1 :(得分:1)
假设您使用的是.NET 4,请使用Task
类。它将在后台线程上运行作业,同时让您的GUI保持响应。
即使您不使用.NET 4,也可以使用简单的多线程类。我很可能会使用BackgroundWorker
。
答案 2 :(得分:0)
试试这个:
var taskA = new Task(() => {
for i = 0 to last record
datarow row = new datarow
put i to row[0]
put names[i] to row[1]
put comments[i] to row[2]
add row to datatable
end for loop
datatable.acceptchanges()
datagridview.datasource = datatable
});
// Start the task.
taskA.Start();
答案 3 :(得分:0)
我会使用任务在后台运行它。然后,在任务运行时,您的UI线程不会被锁定。
var task = new Task(() =>
{
for i = 0 to last record
datarow row = new datarow
put i to row[0]
put names[i] to row[1]
put comments[i] to row[2]
add row to datatable
end for loop
datatable.acceptchanges()
});
// Start the task.
task.Start();
task.ContinueWith(t =>
{
datagridview.datasource = datatable
}, TaskScheduler.FromCurrentSynchronizationContext());
您需要在UI线程中分配数据源,否则您将获得异常。这就是TaskScheduler位将为您做的事情。任务完成后,您的继续将在UI线程上运行(假设您从UI线程设置了延续)。