2011-03-11 63 views
1

我正在開發一個使用BackroundWorker的多線程應用程序。在Do_Work方法中,我調用另一個方法,在該方法中,我使用while語句將大量數據添加到列表中。我的目標是添加列表中要顯示在GridView中的所有數據。我怎麼能這樣做,所以每次數據添加到列表中,gridview取決於?而不是等到while語句完成運行。當while-statment向列表中添加一個值時,該值會插入到gridview中?BackgroundWorker - C#

它必須在ProgressChanged中,但我不知道該怎麼做。

+0

你看過[msdn]上的示例(http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker.onprogresschanged.aspx)嗎? – Blorgbeard 2011-03-11 15:58:01

+0

我有,但我不知道如何正確,以便我的列表值添加到grdiview:S – Lars 2011-03-11 16:00:05

回答

1

This migh幫助。我有一個名爲的WorkerThread類做的工作,我們在的WorkerThread類要

static void Main(string[] args) 
{ 
    // create the background worker object 
    BackgroundWorker _worker = new BackgroundWorker(); 

    // tell the background worker it can be cancelled and report progress 
    _worker.WorkerReportsProgress = true; 
    _worker.WorkerSupportsCancellation = true; 

    // a worker thread object where the actual work happens 
    WorkerThread thread = new WorkerThread(); 

    // add our event handlers 
    _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(thread.RunWorkerCompleted); 
    _worker.ProgressChanged += new ProgressChangedEventHandler(thread.ProgressChanged); 
    _worker.DoWork += new DoWorkEventHandler(thread.DoWork); 

    // start the worker thread 
    _worker.RunWorkerAsync(); 

    // wait for it to be completed 
    while(!_worker.CancellationPending) 
    { 
     // sleep for a second 
     Thread.Sleep(1000); 
    } 

    Console.ReadKey(); 

} 

現在

public class WorkerThread 
{ 
    public void DoWork(object sender, DoWorkEventArgs e) 
    { 
     //get a handle on the worker that started this request 
     BackgroundWorker workerSender = sender as BackgroundWorker; 

     // loop through 10 times and report the progress back to the sending object 
     for(int i = 0; i < 10; i++) 
     { 
      // tell the worker that we want to report progress being made 
      workerSender.ReportProgress(i); 
      Thread.Sleep(100); 
     } 

     // cancel the thread and send back that we cancelled 
     workerSender.CancelAsync(); 
     e.Cancel = true; 

    } 

    public void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     Console.WriteLine("Worker Done!!");   
    } 

    public void ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     // print out the percent changed 
     Console.WriteLine(e.ProgressPercentage); 
    } 
} 

我使用的是自定義類,你可以用你的類中的方法是創建背景工作者。只需修改ProgressChanged事件中的代碼即可。

+0

我該如何做,而不是你console.Writeline ProgressChanged方法添加我的datagridview數據源到列表? – Lars 2011-03-11 19:19:42

2

我的方法是創建一個類,它可以容納我來回傳遞的任何數據。當您致電ReportProgress時,它將需要百分比增量和對象參數。將類放入此對象參數中,並從ProgressChanged事件中通過ProgressChangedEventArgs使此對象可用。然後,您可以讀取這些數據,將其輸入到您想要更新的控件中,然後調用該控件上的Refresh()方法在UI中更新它,而不會凍結該界面。

http://msdn.microsoft.com/en-us/library/a3zbdb1t.aspx

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.progresschanged.aspx

編輯:(僞代碼,未經測試)

private List<Customer> _customerList = new List<Customer>(); 

protected void DoWork(object sender, DoWorkEventArgs e) 
{ 
    MyDataGridView.DataSource = _customerList; // Here is where you'll set your data source and bindings 
    Load_Customer_Method(); 
} 

private void Load_Customer_Method() 
{ 
    int totalCustomers = 20; 
    int currentCustomer = 1; 

    for(currentCustomer = 1; currentCustomer <= totalCustomers; currentCustomer++) 
    { 
     Customer c = new Customer(); 
     // Configure customer 

     ReportProgress(100*currentCustomer/totalCustomers, c); 
    } 
} 

private void ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    Customer addedCustomer = (Customer)e.UserState; 
    _customerList.Add(addedCustomer); // If bindings are set, this update is automatic 
    MyDataGridView.Refresh(); // Force a refresh of the screen for this grid to make 
           // it appear as if the grid is populating one object at 
           // a time. 
} 
+0

我確實將數據保存到我用來傳遞數據的類中。 – Lars 2011-03-11 16:05:29

+0

@Lars:那麼問題是什麼?此對象立即作爲ProgressChangedEventArgs的屬性提供,並可從ProgressChanged事件訪問。 – 2011-03-11 16:12:04

+0

在我的Do_Work方法中,我調用另一種將所有數據添加到列表中的方法。在該方法中運行一個while語句,將數據添加到列表中。那我該怎麼辦? Iam realy對不起,但我有點困惑:S – Lars 2011-03-11 16:27:37

2

給你的工人

添加一個進步改變了事件處理程序在你Do_Work方法

BackgroundWorker worker = sender as BackgroundWorker; 

    worker.ReportProgress(0, new DataObject()) 

在你陸侃處理

DataObject data (DataObject)e.UserState; 
    yourList.Add(data); 

如果你知道你有多長時間了,您可以發送在ReportProgess中的實際完成計數而不是0.

+0

在我的Do_Work方法中,我調用另一種將所有數據添加到列表中的方法。在該方法中運行一個while語句,將數據添加到列表中。那我該怎麼辦? Iam realy抱歉,但我有點困惑:S – Lars 2011-03-11 16:27:20

+0

只需將發件人作爲工人傳入第二種方法即可。 – HadleyHope 2011-03-11 16:34:43

+0

在我的Do_Work中,我調用添加值的方法,該方法不會返回數據,它只是將數據添加到列表中。然後我叫bakgroundworker.ReportProgress(0,cosutmers)。然後在ProgressChanged中,我創建了一個客戶類的實例,其中所有數據都與Customer客戶= e.UserState類似。之後,我調用將gridview.DataSource綁定到列表的方法。我做錯了什麼? – Lars 2011-03-11 19:06:22