2017-03-13 108 views
-1

我有一個大的數據庫(超過10萬),我需要從列防止調用凍結形式的AddRange

這之一的數據填充的組合框的代碼是我現在有

FastecData db = ConnectionHelper.CreateConnection(CurrentLocation); 

List<Fakturor> t = db.Fakturor.OrderBy(z => z.FaktNr).ToList(); 


List<string> st = new List<string>(); 
foreach (var item in t) 
{ 
    _busy.WaitOne(); 
    st.Add(item.FaktNr); 
} 
st.OrderBy(x => x.Length); 

comboBoxFaktNr1.Invoke((Action)(() => 
{ 
    comboBoxFaktNr1.Items.AddRange(st.ToArray()); 
})); 
comboBoxFaktNr2.Invoke((Action)(() => 
{ 
    comboBoxFaktNr2.Items.AddRange(st.ToArray()); 
})); 

這是作爲後臺工作人員運行的。 我使用此代碼的問題是,它運行時.Items.AddRange(st.ToArray()); 表單停止響應約10秒。有沒有辦法阻止表單凍結?

+0

如果你只需要'FaktNr'在組合框中,爲什麼你從數據庫中讀取整個記錄? – dotNET

+4

你真的將100k項目添加到組合框?爲什麼??用戶將無法使用它!更好地存儲它,然後添加用戶請求/過濾出的一些值。 – TaW

+0

另外,如果你使用'BackgroundWorker','_busy'的目的是什麼? – dotNET

回答

2

下面的代碼應該做的一切,你在你的代碼做:

FastecData db = ConnectionHelper.CreateConnection(CurrentLocation); 
var t = db.Fakturor.Select(z => z.FaktNr).OrderBy(z => z).ToArray(); 

comboBoxFaktNr1.Invoke(new Action(() => { 
    int x = 0; 
    while(t.Length - x > 0) 
    { 
    var t2 = t.Skip(x).Take(Math.Min(t.Length - x, 1000)); 
    comboBoxFaktNr1.Items.AddRange(t2); 
    comboBoxFaktNr2.Items.AddRange(t2); 
    x += 1000; 
    Application.DoEvents(); 
    } 
})); 

但同樣,你應該考慮在組合框中有100K的項目是對人類的犯罪。考慮多級過濾以將項目數量減少到可用大小。

+0

當試圖運行此代碼時,我得到'附加信息:跨線程操作無效:控制'comboBoxFaktNr1'從其創建的線程以外的線程訪問。'錯誤。我也必須將其更改爲'comboBoxFaktNr1.Items.AddRange(t.ToArray());'使其運行甚至可以運行 – Drago87

+0

這給了我一個'不能將lambda表達式轉換爲'System.Delegate'類型,因爲它不是委託(( – Drago87

+0

)如果你做了這麼多的工作,你應該考慮用'BeginInvoke'來替換'Invoke'並且是的:犯罪再次成爲人性化的D – Radinator