开发者

BackgroundWorker - C#

I am developing a multithreading application using BackroundWorker. In the Do_Work method I call a开发者_JAVA技巧nother method, in that method I add a lot of data into a list using a while-statement. My goal is to add all the data that in the list to show in a GridView. How can I do that so every time data adds to the list, the gridview uppdates? Instead of waiting until that the while-statement has finished running. When the while-statment adds a value to the list, the value inserts into the gridview?

It must be in the ProgressChanged, but I dont know how to do that.


Add a progress changed event handler to your worker

In your Do_Work method

   BackgroundWorker worker = sender as BackgroundWorker;

   worker.ReportProgress(0, new DataObject())

In your progess handler

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

If you know how far you are along you can send the actual done count in ReportProgess instead of 0.


My method was to create a class that would hold any data that I am passing back and forth. When you call ReportProgress it will require the percentage increment and an object argument. You put your class into this object argument, and from the ProgressChanged event this object is made available through the ProgressChangedEventArgs. You can then read this data, input it into the control you are wanting to update and then call the Refresh() method on that control to update it in the UI without freezing the interface.

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

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

Edit: (psuedocode, untested)

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. 
}


This might help. I have a class called WorkerThread that does the work we want

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();

}

Now in the WorkerThread class

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 );
    }
}

I am using a custom class, you could use a method in your class that is creating the background worker. Just modify the code in the ProgressChanged event.


I suggest you to read on the backgroundworker. You have all the info and example there :

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

All you will need to do is to pass your item as parameter in ReportProgress and in the event ProgressChanged add your item in your grid.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜