C# 长时间的计算使程序无法响应

C# 长时间的计算使程序无法响应,c#,dictionary,datagridview,C#,Dictionary,Datagridview,我有一个程序,可以对数百万条记录进行彻底的计算。有时,它运行一个多小时,有时大约30分钟。在此期间,程序没有响应或无法单击。有什么解决办法吗?比如,加载鼠标图标 另一个问题是,如果我将两个字典作为datagrid的数据源,那么与读取csv文件并将其放入datagrid相比,它的速度非常慢。以下是算法: for i = 0 to last record datarow row = new datarow put i to row[0] put names[i] to row

我有一个程序,可以对数百万条记录进行彻底的计算。有时,它运行一个多小时,有时大约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

注:名称[i]和注释[i]是字典。然而,如果我只是从一个具有几乎相同循环的csv文件中读取,并将其放入datatable中,并将其作为datagridview的数据源,则速度会更快(大约5-10分钟,而使用20分钟的字典)。有什么解决方法吗?

您所要做的就是使用一点多线程来在UI线程以外的线程上执行长时间运行的进程:

var task = new Task(() =>
{
    // do some work to get your dataTable
    dataTable.AcceptChanges();
    datagridview
        .Invoke(new Action(() => datagridview.DataSource = dataTable));
});

task.Start();

您所要做的就是使用一点多线程来在UI线程以外的线程上执行长时间运行的进程:

var task = new Task(() =>
{
    // do some work to get your dataTable
    dataTable.AcceptChanges();
    datagridview
        .Invoke(new Action(() => datagridview.DataSource = dataTable));
});

task.Start();

假设您使用的是.NET4,请使用该类。它将在后台线程上运行作业,同时让GUI保持响应


即使您不使用.NET4,也有一些简单的多线程类可用。我很可能会使用
BackgroundWorker

假设您使用的是.NET4,请使用该类。它将在后台线程上运行作业,同时让GUI保持响应

即使您不使用.NET4,也有一些简单的多线程类可用。我很可能会使用
BackgroundWorker

尝试以下方法:

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();
试试这个:

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();

我会使用一个任务在后台运行它。这样,在任务运行时,您的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线程设置延续)。

我将使用任务在后台运行此任务。这样,在任务运行时,您的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线程设置延续)。

在另一个线程中执行该操作以停止挂起。谷歌:“多线程C#”在另一个线程中执行,以停止挂起。谷歌:“多线程C#”我想我会把这个标记为答案,因为这对我来说是最好的答案。如果你不介意的话,我还有一个问题。由于此“注释”窗口在计算完成后显示,我如何使其在计算一条记录后生成注释,例如,当您正在安装某些内容时,安装程序会显示已提取的所有文件far@MindSeeker老实说,我不太明白你的意思。这是一个单独的过程,还是说在添加行时显示行?如果你想在行出现时添加行,你必须做一些与Justin的答案非常相似的事情。在迭代过程中,执行datagridview.Invoke(新操作(()=>{code to add a row}));在循环中直接向datatable添加一行。实际上,每隔10-100条记录做一次可能是个好主意。很抱歉,回复太晚了。我的意思是,每一次计算都会输出一条注释,我希望在一次计算完成时看到它,而不是在所有计算之后。如果我使用Justin的答案,那么我必须将datatable.AcceptChanges()放在下面;调用(新操作(()=>datagridview.DataSource=dataTable));添加行之后?我想我会将此标记为答案,因为这是我的最佳答案。如果你不介意的话,我还有一个问题。由于此“注释”窗口在计算完成后显示,我如何使其在计算一条记录后生成注释,例如,当您正在安装某些内容时,安装程序会显示已提取的所有文件far@MindSeeker老实说,我不太明白你的意思。这是一个单独的过程,还是说在添加行时显示行?如果你想在行出现时添加行,你必须做一些与Justin的答案非常相似的事情。在迭代过程中,执行datagridview.Invoke(新操作(()=>{code to add a row}));在循环中直接向datatable添加一行。实际上,每隔10-100条记录做一次可能是个好主意。很抱歉,回复太晚了。我的意思是,每一次计算都会输出一条注释,我希望在一次计算完成时看到它,而不是在所有计算之后。如果我使用Justin的答案,那么我必须将datatable.AcceptChanges()放在下面;调用(新操作(()=>datagridview.DataSource=dataTable));在添加行之后?