2011-09-20 59 views
2

我正在開發一個winform應用程序,並會在數據庫中發出請求並異步填充我的組合框,但由於它們來自另一個線程,因此存在訪問控制問題,下面是代碼。Linq to Sql導致組合框異步

this.backWorker.DoWork + = delegate 
      { 
       comboBoxUsers.DataSource = repositoryUser.SelectAll(); 
       comboBoxUsers.ValueMember = "UserId"; 
       comboBoxUsers.DisplayMember = "Name"; 
      }; 

      backWorker.RunWorkerAsync(); 

我學習有關envoke但我遇到了麻煩來實現這一點, 我需要做的就是離開DoWork的事件可見的進度欄,並選擇這樣做。

回答

3

只查詢您的BackgroundWorker的存儲庫,並通過ProgressChangedEvenHandler結果返回給用戶界面

//Set the ComboBox Properties on the Form, not in the worker. 
    comboBoxUsers.ValueMember = "UserId"; 
    comboBoxUsers.DisplayMember = "Name"; 

    BackgroundWorker = new BackgroundWorker(); 
    worker.DoWork += Worker_DoWork; 
    worker.WorkerReportsProgress = true; 
    worker.ProgressChanged += new ProgressChangedEventHandler(Worker_ProgressChanged); 

    private void Worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgrounderWorker worker = (BackgroundWorker)sender; 

     //Query the database 
     //Instantiate a custom-class to contain the results 
     IList<Users> users = userRepository.SelectAll(); 
     QueryResults results = new QueryResults(users); 
     worker.ReportProgress(0, results); 
    } 

    //Back In the UI Layer 
    private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     var result = (QueryResult)e.UserState; 
     comboBoxUsers.DataSource = result.Users; 
    } 
+0

另外,如果ComboBox的ValueMember和DisplayMember永遠不會改變,您可以在窗體的構造函數或關聯的designer.cs文件中設置它們。唯一真正關心的是將查詢結果返回給主線程。 – Dubs

0

您的代理應該這樣寫:

this.backWorker.DoWork += delegate(object s, DoWorkEventArgs args) 
{ 
    //... 
} 

關於如何從另一個線程訪問UI線程的UI控件在這裏看到的細節:

Access windows control from Backgroundworker DoWork

有一個明確的回答這個鏈接,這裏是一個片段:

this.Invoke(new MethodInvoker(delegate { 

    // This code executes on the GUI thread. 

})); 
+0

不太明白,我怎麼訪問組合框? – fernando