如何避免在运行时更新数据源时控件被冻结?
How to avoid the control gets freeze while updating the datasource at runtime?
我在 WinForms 应用程序中工作,并在我的应用程序中使用了 DataGridView 控件。最初,我在其中加载了 10000 行和 50 列。我的场景是在特定时间间隔更新数据源(使用定时器)。
问题: 在更新数据源时执行操作(cell_click、滚动等)时,网格已 frozen/gang。
如何解决这个问题?有什么解决方法吗?请提出您的想法。
到目前为止,这是我的代码:
private void timer1_Tick(object sender, EventArgs e)
{
//try
{
timer.Stop();
for (int i = 0; i < 10000; i++)
{
var row = r.Next() % 10000;
for (int col = 1; col < 10; col++)
{
var colNum = r.Next() % 55;
if (table != null)
table.Rows[row][colNum] = "hi";// r.Next().ToString();
}
}
table.AcceptChanges();
timer.Start();
}
}
这是一个示例输出:
[https://drive.google.com/open?id=0B9MOGv1FOt-TQ1BNZWtnRktxeXc]
谢谢。
其中一个解决方案是在如此长的 运行 操作期间调用 Application.DoEvents()
。这是示例
private void timer1_Tick(object sender, EventArgs e)
{
//try
{
timer.Stop();
for (int i = 0; i < 10000; i++)
{
var row = r.Next() % 10000;
for (int col = 1; col < 10; col++)
{
var colNum = r.Next() % 55;
if (table != null)
table.Rows[row][colNum] = "hi";// r.Next().ToString();
}
Application.DoEvents(); //add this line
}
table.AcceptChanges();
timer.Start();
}
}
另一种解决方案是将长 运行 任务移动到单独的线程。
尝试使用 BackgroundWorker。
BackgroundWorker is a helper class in the System.ComponentModel
namespace for managing a worker thread. It can be considered a
general-purpose implementation of the EAP(The Event-Based Asynchronous Pattern), and provides the following
features:
A cooperative cancellation model
The ability to safely update WPF or Windows Forms controls when the worker completes
- Forwarding of exceptions to the completion event
- A protocol for reporting progress
- An implementation of IComponent allowing it to be sited in Visual Studio’s designer
您可以在下面找到示例,请根据您的计时器进行调整:
class Program
{
static BackgroundWorker _bw = new BackgroundWorker();
static void Main()
{
_bw.DoWork += bw_DoWork;
_bw.RunWorkerAsync ("Message to worker");
Console.ReadLine();
}
static void bw_DoWork (object sender, DoWorkEventArgs e)
{
// This is called on the worker thread
Console.WriteLine (e.Argument); // writes "Message to worker"
// Perform time-consuming task...
//update your grid
for (int i = 0; i < 10000; i++)
{
var row = r.Next() % 10000;
for (int col = 1; col < 10; col++)
{
var colNum = r.Next() % 55;
if (table != null)
table.Rows[row][colNum] = "hi";r.Next().ToString();
}
}
table.AcceptChanges();
}
}
我在 WinForms 应用程序中工作,并在我的应用程序中使用了 DataGridView 控件。最初,我在其中加载了 10000 行和 50 列。我的场景是在特定时间间隔更新数据源(使用定时器)。
问题: 在更新数据源时执行操作(cell_click、滚动等)时,网格已 frozen/gang。
如何解决这个问题?有什么解决方法吗?请提出您的想法。
到目前为止,这是我的代码:
private void timer1_Tick(object sender, EventArgs e)
{
//try
{
timer.Stop();
for (int i = 0; i < 10000; i++)
{
var row = r.Next() % 10000;
for (int col = 1; col < 10; col++)
{
var colNum = r.Next() % 55;
if (table != null)
table.Rows[row][colNum] = "hi";// r.Next().ToString();
}
}
table.AcceptChanges();
timer.Start();
}
}
这是一个示例输出:
[https://drive.google.com/open?id=0B9MOGv1FOt-TQ1BNZWtnRktxeXc]
谢谢。
其中一个解决方案是在如此长的 运行 操作期间调用 Application.DoEvents()
。这是示例
private void timer1_Tick(object sender, EventArgs e)
{
//try
{
timer.Stop();
for (int i = 0; i < 10000; i++)
{
var row = r.Next() % 10000;
for (int col = 1; col < 10; col++)
{
var colNum = r.Next() % 55;
if (table != null)
table.Rows[row][colNum] = "hi";// r.Next().ToString();
}
Application.DoEvents(); //add this line
}
table.AcceptChanges();
timer.Start();
}
}
另一种解决方案是将长 运行 任务移动到单独的线程。
尝试使用 BackgroundWorker。
BackgroundWorker is a helper class in the System.ComponentModel namespace for managing a worker thread. It can be considered a general-purpose implementation of the EAP(The Event-Based Asynchronous Pattern), and provides the following features:
A cooperative cancellation model
The ability to safely update WPF or Windows Forms controls when the worker completes
- Forwarding of exceptions to the completion event
- A protocol for reporting progress
- An implementation of IComponent allowing it to be sited in Visual Studio’s designer
您可以在下面找到示例,请根据您的计时器进行调整:
class Program
{
static BackgroundWorker _bw = new BackgroundWorker();
static void Main()
{
_bw.DoWork += bw_DoWork;
_bw.RunWorkerAsync ("Message to worker");
Console.ReadLine();
}
static void bw_DoWork (object sender, DoWorkEventArgs e)
{
// This is called on the worker thread
Console.WriteLine (e.Argument); // writes "Message to worker"
// Perform time-consuming task...
//update your grid
for (int i = 0; i < 10000; i++)
{
var row = r.Next() % 10000;
for (int col = 1; col < 10; col++)
{
var colNum = r.Next() % 55;
if (table != null)
table.Rows[row][colNum] = "hi";r.Next().ToString();
}
}
table.AcceptChanges();
}
}