2011-06-23 21 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不是線程安全的。

相關問題