1

I am writing a program which does a lot of processes at once. To keep the user from thinking the program crashed, I decided to add a "Please Wait" window. Everything works fine except for one thing: the form doesn't fully render until 30 seconds later. Before that the "Please wait until..." text that is supposed to be in the form is just a white rectangle.

Can you please tell me how I can fix this issue? Thanks!

Edit:

As I assumed everyone had a crystal ball and could read my virtual mind, I forgot to include the code >.>;;

Here it is:

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    Dim pleasewait As New TestEspere
    CenterForm(pleasewait)
    pleasewait.Show()
    Dim quantity, quantity_purchased As Integer
    Dim tracking_usps, lybro_id, recipient_name, order_id, order_item_id, payments_transaction_id, product_id, description, listing_id, sku,
           batch_id, buyer_email, buyer_name, address_1, address_2,
        city, state, zip, country, special_comments, upc, status_shipment, loc, tracking, etc, eff As String
    Dim total_price, peso, order_price, shipping_price As Decimal
    Dim purchase_date, payments_date As Date

    For i = 0 To DataGridView1.Rows.Count - 1
        On Error GoTo netx
        If IsDBNull(DataGridView1(0, i).Value) Then Exit For
        DataGridView1(33, i).Value = TrackingRequest(Replace(DataGridView1(32, i).Value, "'", ""))

        lybro_id = DataGridView1(0, i).Value
        order_id = DataGridView1(1, i).Value
        order_item_id = If(IsDBNull(DataGridView1(2, i).Value), "", DataGridView1(2, i).Value)
        payments_date = String.Format("{0:yyyy-MM-dd}", DataGridView1(3, i).Value.ToString)
        quantity = DataGridView1(4, i).Value
        payments_transaction_id = If(IsDBNull(DataGridView1(5, i).Value), "", DataGridView1(5, i).Value)
        product_id = DataGridView1(6, i).Value
        description = Replace(DataGridView1(7, i).Value, "'", "''")
        peso = DataGridView1(8, i).Value
        listing_id = If(IsDBNull(DataGridView1(9, i).Value), "", DataGridView1(9, i).Value)
        sku = DataGridView1(10, i).Value
        order_price = DataGridView1(11, i).Value
        shipping_price = DataGridView1(12, i).Value
        quantity_purchased = DataGridView1(13, i).Value
        total_price = DataGridView1(14, i).Value
        purchase_date = String.Format("{0:yyyy-MM-dd}", DataGridView1(15, i).Value.ToString )
        batch_id = If(IsDBNull(DataGridView1(16, i).Value), "", DataGridView1(16, i).Value)
        buyer_email = DataGridView1(17, i).Value
        buyer_name = Replace(DataGridView1(18, i).Value, "'", "''")
        recipient_name = Replace(DataGridView1(19, i).Value, "'", "''")
        address_1 = Replace(DataGridView1(20, i).Value, "'", "''")
        address_2 = If(IsDBNull(DataGridView1(21, i).Value), "", DataGridView1(21, i).Value)
        city = Replace(DataGridView1(22, i).Value, "'", "''")
        state = If(IsDBNull(DataGridView1(23, i).Value), "", Replace(DataGridView1(23, i).Value, "'", "''"))
        zip = DataGridView1(24, i).Value
        country = Replace(DataGridView1(25, i).Value, "'", "''")
        special_comments = If(IsDBNull(DataGridView1(26, i).Value), "", Replace(DataGridView1(26, i).Value, "'", "''"))
        upc = If(IsDBNull(DataGridView1(27, i).Value), "", DataGridView1(27, i).Value)
        etc = If(IsDBNull(DataGridView1(28, i).Value), "", DataGridView1(28, i).Value)
        status_shipment = DataGridView1(29, i).Value
        loc = Replace(DataGridView1(30, i).Value, "'", "''")
        eff = If(IsDBNull(DataGridView1(31, i).Value), "", DataGridView1(31, i).Value)
        tracking = If(IsDBNull(DataGridView1(32, i).Value), "", DataGridView1(32, i).Value)
        tracking_usps = Replace(DataGridView1(33, i).Value, "'", "''")

        Cmd.CommandText = String.Format("INSERT INTO re_orders_con_pesos(re_lybro_id, re_order_id, re_order_item_id, re_payments_date, re_quantity, re_payments_transaction_id, re_product_id,
                            re_description, re_peso, re_listing_id, re_sku, re_order_price, re_shipping_price, re_quantity_purchased, re_total_price, re_purchase_date, re_batch_id, re_buyer_email,
                            re_buyer_name, re_recipient_name, re_ship_address_1, re_ship_address_2, re_ship_city, re_ship_state, re_ship_zip, re_ship_country, re_special_comments, re_upc, re_etc, re_status_shipment,
                            re_location, re_eff, re_tracking, re_tracking_usps, re_status_email, re_status_db) VALUES('{0}','{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}','{32}', '{33}','{34}','{35}')", lybro_id, order_id, order_item_id, payments_date, quantity, payments_transaction_id,
                                        product_id, description, peso, listing_id, sku, order_price, shipping_price, quantity_purchased, total_price, purchase_date, batch_id, buyer_email,
                                        buyer_name, recipient_name, address_1, address_2, city, state, zip, country, special_comments, upc, etc, status_shipment, loc, eff, tracking, tracking_usps,
                                        ESTATUS_EMAIL_NUEVO, ESTATUS_DB_NUEVO)
        Cmd.Execute()
netx:
    Next

    pleasewait.Close()

    Beep()
End Sub
Julio Garcia
  • 393
  • 2
  • 7
  • 22
  • 1
    Can you tell us what code have you written? A mind reader or a crystall ball should not be required to help you. – Steve Nov 05 '16 at 16:27
  • 2
    My crystal ball tells me you are doing all this processing on the UI thread – djv Nov 05 '16 at 16:27
  • @Steve I am terribly sorry for this, I added it – Julio Garcia Nov 05 '16 at 16:34
  • @Verdolino UI thread? – Julio Garcia Nov 05 '16 at 16:34
  • 2
    You can add an Application.DoEvents after the call to show the form. This will give the pause to your code and allow the form engine to paint your waiting form. BUT be warned of the troubles that Application.DoEvents introduce. See this [answer from Hans Passant](http://stackoverflow.com/a/5183623/1197518) It would be better to use a separate task to do your calculations. – Steve Nov 05 '16 at 16:46
  • It is going to be a while before you'll learn not to write code like this. That can't be rushed that easily. Meanwhile, add `pleasewait.Update()` after the Show() call to get this program completed and give you time to learn. – Hans Passant Nov 05 '16 at 16:53
  • 2
    There are much, much easier ways to get data from a DGV to a DB - it only takes one line of code binding it to a DataTable. DB ops just arent that tedious – Ňɏssa Pøngjǣrdenlarp Nov 05 '16 at 17:02
  • @Plutonix Can I use a DataTable even though I am adding something other that what the table has? – Julio Garcia Nov 05 '16 at 17:06
  • how can you save something if there is no column for it? – Ňɏssa Pøngjǣrdenlarp Nov 05 '16 at 17:16

1 Answers1

1

The code for the button click event handler is run on the UI's thread. This thread is supposed to handle your display only, but you are moving data around on it and using it to store information to your database. There is simply too much wrong to attempt to solve all your problems, so I, and the other commenters, propose a band-aid: Application.DoEvents. The placement below will allow your UI to respond to your events and update before you process each row in the datagridview.

Also, on error goto is deprecated, so I replaced it with the newer functional equivalent Try .. Catch

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    Dim pleasewait As New TestEspere
    CenterForm(pleasewait)
    pleasewait.Show()
    ' ... (code removed for brevity)

    For i = 0 To DataGridView1.Rows.Count - 1
        ' This call will allow your pleasewait form to update
        Application.DoEvents()
        Try
            If IsDBNull(DataGridView1(0, i).Value) Then Exit For
            DataGridView1(33, i).Value = TrackingRequest(Replace(DataGridView1(32, i).Value, "'", ""))
            lybro_id = DataGridView1(0, i).Value
            ' ... (code removed for brevity)
            tracking_usps = Replace(DataGridView1(33, i).Value, "'", "''")
            Cmd.CommandText = String.Format("INSERT INTO re_orders_con_pesos(re_lybro_id, re_order_id, re_order_item_id, re_payments_date, re_quantity, re_payments_transaction_id, re_product_id,
                        re_description, re_peso, re_listing_id, re_sku, re_order_price, re_shipping_price, re_quantity_purchased, re_total_price, re_purchase_date, re_batch_id, re_buyer_email,
                        re_buyer_name, re_recipient_name, re_ship_address_1, re_ship_address_2, re_ship_city, re_ship_state, re_ship_zip, re_ship_country, re_special_comments, re_upc, re_etc, re_status_shipment,
                        re_location, re_eff, re_tracking, re_tracking_usps, re_status_email, re_status_db) VALUES('{0}','{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}','{32}', '{33}','{34}','{35}')", lybro_id, order_id, order_item_id, payments_date, quantity, payments_transaction_id,
                                    product_id, description, peso, listing_id, sku, order_price, shipping_price, quantity_purchased, total_price, purchase_date, batch_id, buyer_email,
                                    buyer_name, recipient_name, address_1, address_2, city, state, zip, country, special_comments, upc, etc, status_shipment, loc, eff, tracking, tracking_usps,
                                    ESTATUS_EMAIL_NUEVO, ESTATUS_DB_NUEVO)
            Cmd.Execute()
        Catch
            ' you are ignoring exceptions, but this is where you should be handling them!
        End Try
    Next

    pleasewait.Close()
    Beep()
End Sub

Under normal circumstance, I can't think of a reason to ever use Application.DoEvents. In your case, a solution without it would require too significant a rewrite to your application.

djv
  • 15,168
  • 7
  • 48
  • 72
  • A proper way is to use a delegate to update, not force the events. Minor changes at that and is proper to do so. Better would to be create a separate wait class so it can be handled on its own thread not the same one as a button click event.... – Trevor Nov 05 '16 at 19:42
  • Absolutely, there are numerous other ways which are far superior. There's just too much to change here. This answer is in the same vein of Hans' comment to the question in that although ideally a lot should be changed, this should get the OP going. I pointed this out in my answer. – djv Nov 05 '16 at 20:12