2011-06-23 36 views
0

我有一个功能LoadData与大量的WinForm控件,它将数据从数据库加载到控件。 现在它变得很慢,我应该使用线程,如果是,那么请提出一个很好的示例,我已经试过MSDN sample任何人都有线程安全调用的好样本?

但它不是对我很有用,它会需要很多的变化在我的代码。

+0

你必须确定你正在加载什么样的数据,以及如何;以及你在做什么 –

+0

另外,一般来说,线程几乎总是需要大量的重新工作,特别是如果核心代码的设计没有考虑线程的话...... –

+0

你最好打赌可以看看你加载了多少数据看看你是否找不到加载子集的方法。 – Tod

回答

1

我假设你有很多与UI交互的代码,并且你想从后台线程中完成。

你可以添加一个方法是这样的:

private static void UpdateControl(Control control, Action action) 
{ 
    if (control.InvokeRequired) 
     control.Invoke(action); 
    else 
     action(); 
} 

用法:

textBox.Text = "Something"; 

UpdateControl(textbox,() => { textBox.Text = "Something" }); 

或扩展方法,使用途更短

public static class ControlExtension 
{ 
    public static void UpdateControl(this Control control, Action<Control> action) 
    { 
     if (control.InvokeRequired) 
      control.Invoke((Action)(() => action(control))); 
     else 
      action(control); 
    } 
} 

用法:

textBox.UpdateControl(arg => arg.Text = "Something"); 
+0

非常好的简洁的答案。总理候选人的扩展方法IYAM – sehe

+0

@sehe - yep。更新。 –

+0

@Alex Aza:如果函数有8/10个控件或者可能超过那个,那么control.InvokeRequired和control.Invoke会在同一时间执行。 – Akhil

0

您可以使用.NET 4中的TPL以更简单的方式处理此问题。你所需要做的就是传递一个合适的TaskScheduler。通过从UI上下文创建的TaskScheduler,任何调用都可以轻松包装到Task中,并根据需要在UI线程上执行。

有关详细信息,请参阅我的blog post on the subject

0

退房BackgroundWorker

var bw = new BackgroundWorker(); 
bw.DoWork += (s, e) => e.Result = getAllBoxers(); 
bw.RunWorkerCompleted += (s, e) => 
    { 
     var boxers = e.Result as List<Boxer>; 
     dgvBoxers.DataSource = boxers; 
    }; 
bw.RunWorkerAsync(); 

确保永远不会做任何会影响DoWork因为GUI WinForms不是线程安全的。

相关问题