블로그 이미지
Sunny's

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

2009. 9. 2. 18:46 .NET Framework

Summary

This article will show you how to safely get data into a WinGrid using the Background Worker component found in .NET 2.0

Additional Information

Many times an application will need to perform many actions that consume some time before they complete. During this time while the actions are being performed, the user interface becomes what appears to be “frozen” until the actions are complete. Some examples of actions that are performed are fetching data from a database or perhaps a long complex loop to do something. Any of these lengthy processes degrade our application user’s experience and can make a good application hard and frustrating to use. This article will show how we can leverage the really great new Background Worker component to fetch new Customer objects and pass them to the WinGrid. After reading this article please download the included sample that is available in both C# and VB.NET.

Step-By-Step Example

First things first, the new Background Worker component given to us in Visual Studio 2005 / .NET 2.0 wraps up patterns and functionality that we would have otherwise coded ourselves just as we always have back in Visual Studio 200X / .NET 1.X. This component makes the creation of an async process as well as its handling very simple through the three events that fire as well as some simple properties and methods that we use.

In this example, we have a use case where the application loads up and we have a WinGrid bound to an empty collection of Customer objects. Note: the CustomerCollection is simply an implementation of BindingList of type Customer (a custom business object in this project). When we press the “Get Data” button, we are fetching new Customer objects from somewhere, in another thread and then adding them to the WinGrid. We are also updating the user interface (through the UltraProgressBar) to let the users know how much longer there is to go before the process is complete. We can also allow the users to cancel the operation if it is taking too long and they want to go to lunch.

The code to accomplish this is quite simple. To start off, we simply drag and drop an instance of the Background Worker component (located in the “Components” toolbox tab in Visual Studio 2005) and add the event handlers for “DoWork”, “ProgressChanged” and “RunWorkerCompleted”.

Now all that is left for us to do is to fill these event handlers with code to get these customers, update the elements on the user interface and close and clean things up.

Getting the Data:

On the Click event handler of the button we will start this process as follows:

C#
        private void btnGetData_Click(object sender, EventArgs e)
        {
            this.btnGetData.Enabled = false;
            this.lblMessage.Text = "Getting Records, Please Wait...";

            this.bgwData.RunWorkerAsync();
        }

VB.NET

    Private Sub btnGetData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetData.Click
        Me.btnGetData.Enabled = False
        Me.lblMessage.Text = "Getting Records, Please Wait..."

        Me.bgwData.RunWorkerAsync()
    End Sub

Now that we have invoked the process through the “RunWorkerAsync( )” method, we need to handle the “DoWork” event of the Background Worker:

C#

        private void bgwData_DoWork(object sender, DoWorkEventArgs e)
        {
            //This is a new instance of a Customers collection that
            //may have been fetched from a DB or wherever.
            CustomerCollection newCustomers = new CustomerCollection();

            //This simulates the known number of objects that
            //were (or are about to be) returned
            int returnedRecordCount = 100;

            //Here we loop through and add a new instance of
            //a customer object to the collection and each iteration
            //we check to see if someone cancelled the operation
            for (int i = 1; i <= returnedRecordCount ; i++)
            {
                if (this.bgwData.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                Customer theCustomer = new Customer(DateTime.Now.Ticks, Guid.NewGuid().ToString());
                
                newCustomers.Add(theCustomer);

                //Here is where we use this method to pass back
                //information to the UI Thread. Notice how we
                //pass the current progress (limited from 0 to 100)
                //as well as the actual customer object.
                this.bgwData.ReportProgress(i, theCustomer);

                System.Threading.Thread.Sleep(20);
            }
        }

VB.NET

Private Sub bgwData_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwData.DoWork

        'This is a new instance of a Customers collection that
        'may have been fetched from a DB or wherever.
        Dim newCustomers As CustomerCollection = New CustomerCollection()

        'This simulates the known number of objects that
        'were (or are about to be) returned
        Dim returnedRecordCount As Integer = 100


        'Here we loop through and add a new instance of
        'a customer object to the collection and each iteration
        'we check to see if someone cancelled the operation
        For i As Integer = 1 To returnedRecordCount

            If Me.bgwData.CancellationPending Then
                e.Cancel = True
                Return
            End If

            Dim theCustomer As Customer = New Customer(DateTime.Now.Ticks, Guid.NewGuid().ToString())

            newCustomers.Add(theCustomer)

            'Here is where we use this method to pass back
            'information to the UI Thread. Notice how we
            'pass the current progress (limited from 0 to 100)
            'as well as the actual customer object.
            Me.bgwData.ReportProgress(i, theCustomer)

            System.Threading.Thread.Sleep(20)

        Next


    End Sub

The great thing about how this works is that the Background Worker component has the “ReportProgress( )” method which allows us to pass a number between 0 and 100 so that a status bar can be updated easily. Even more important, we can also pass objects so that we can safely get our object instances back to the User Interface thread and do with it as we please. In this case, with each loop iteration, we pass through a Customer object.

..Continued

Samples

wingrid_background_worker.zip
 Sample Application for Background Worker Component and WinGrid

참조 : http://devcenter.infragistics.com/Support/KnowledgeBaseArticle.Aspx?ArticleID=9838
posted by Sunny's