我有一個功能LoadData
與大量的WinForm控件,它將數據從數據庫加載到控件。 現在它變得很慢,我應該使用線程,如果是,那麼請提出一個很好的示例,我已經試過MSDN sample任何人都有線程安全調用的好樣本?
但它不是對我很有用,它會需要很多的變化在我的代碼。
我有一個功能LoadData
與大量的WinForm控件,它將數據從數據庫加載到控件。 現在它變得很慢,我應該使用線程,如果是,那麼請提出一個很好的示例,我已經試過MSDN sample任何人都有線程安全調用的好樣本?
但它不是對我很有用,它會需要很多的變化在我的代碼。
我假設你有很多與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");
您可以使用.NET 4中的TPL以更簡單的方式處理此問題。你所需要做的就是傳遞一個合適的TaskScheduler
。通過從UI上下文創建的TaskScheduler
,任何調用都可以輕鬆包裝到Task
中,並根據需要在UI線程上執行。
有關詳細信息,請參閱我的blog post on the subject。
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不是線程安全的。
你必須確定你正在加載什麼樣的數據,以及如何;以及你在做什麼 –
另外,一般來說,線程幾乎總是需要大量的重新工作,特別是如果核心代碼的設計沒有考慮線程的話...... –
你最好打賭可以看看你加載了多少數據看看你是否找不到加載子集的方法。 – Tod