0

Hi,

just started today with trying to implement a Thread in my application and have come across a problem that I can't seem to figure out.

The application asks the user to enter their userid into a TextBox on the main form which is used to download a specific XML file after they click a button.

If the user has entered an invalid id then a 400 (Bad Request) exception is generated.

I can catch this exception without any problem but then I wish to return the user to the TextBox on the main form to re-enter their id.
I was using this:-

catch (Exception) // Check to make sure the StoreID that has been entered is actually valid 
                {
                    MessageBox.Show("Your request has returned an error. This can be because of two reasons: \n\ni. You have enetered an invalid Store ID. \n\nii. The Cafe Press API is currently down. \n\nPlease try again. ", "Bad Request", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    StoreIDtb.Text = "";
                    StoreIDtb.Focus();
                    return;   
                }

The problem is that I get another error with this:-


- Thrown: "Cross-thread operation not valid: Control 'StoreIDtb' accessed from a thread other than the thread it was created on." (System.InvalidOperationException) Exception Message = "Cross-thread operation not valid: Control 'StoreIDtb' accessed from a thread other than the thread it was created on.", Exception Type = "System.InvalidOperationException"

Now I can see why this is happening but how can I rectify it?

I have tried in testing to remove anything that caused this 'cross-thread' issue to make the 'catch' block as:-

catch (Exception) // Check to make sure the StoreID that has been entered is actually valid 
                {
                    MessageBox.Show("Your request has returned an error. This can be because of two reasons: \n\ni. You have enetered an invalid Store ID. \n\nii. The Cafe Press API is currently down. \n\nPlease try again. ", "Bad Request", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

but then I get this error:-


+ Thrown: "Object reference not set to an instance of an object." (System.NullReferenceException) Exception Message = "Object reference not set to an instance of an object.", Exception Type = "System.NullReferenceException"


in the 'finally' block which is straight after the 'catch' block

It's hard to know how much of the code to post here, so I'll do my best. Here is the majority of the code in question, if any more is required, please let me know.

private void Download(object startPoint)
        {
                try
                {
                    string DIRpath = Path.Combine(Application.StartupPath, "Raw XML"); // Create a holding folder for the raw XML
                    Directory.CreateDirectory(DIRpath);

                    // Put the object argument into an int variable
                    int startPointInt = Convert.ToInt32(startPoint);
                    // Create a request to the file we are downloading
                    webRequest = (HttpWebRequest)WebRequest.Create("http://open-api.cafepress.com/product.countDeepByStore.cp?v=3&appKey={api-key}&storeId=" + StoreIDtb.Text);
                    // Set the starting point of the request
                    webRequest.AddRange(startPointInt);

                    // Set default authentication for retrieving the file
                    webRequest.Credentials = CredentialCache.DefaultCredentials;
                    // Retrieve the response from the server
                    webResponse = (HttpWebResponse)webRequest.GetResponse();
                    // Ask the server for the file size and store it
                    Int64 fileSize = webResponse.ContentLength;

                    // Open the URL for download 
                    strResponse = webResponse.GetResponseStream();
                    if (startPointInt == 0)
                    {
                    strLocal = new FileStream(DIRpath + "/" + StoreIDtb.Text + "-ItemCount.xml", FileMode.Create, FileAccess.Write, FileShare.None);
                    }
                    // It will store the current number of bytes we retrieved from the server
                    int bytesSize = 0;
                    // A buffer for storing and writing the data retrieved from the server
                    byte[] downBuffer = new byte[2048];

                    // Loop through the buffer until the buffer is empty
                    while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
                    {
                    // Write the data from the buffer to the local hard drive
                    strLocal.Write(downBuffer, 0, bytesSize);
                    // Invoke the method that updates the form's label and progress bar
                    this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { strLocal.Length, fileSize + startPointInt });
                    }
                }
                    catch (Exception) // Check to make sure the StoreID that has been entered is actually valid 
                {
                    MessageBox.Show("Your request has returned an error. This can be because of two reasons: \n\ni. You have enetered an invalid Store ID. \n\nii. The Cafe Press API is currently down. \n\nPlease try again. ", "Bad Request", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    StoreIDtb.Text = "";
                    StoreIDtb.Focus();
                    return;   
                }

            finally
            {
                // When the above code has ended, close the streams
                strResponse.Close();
                strLocal.Close();
            }
        }

Regards..,

MT

Edited by Cap'nKirk: n/a

1
Contributor
1
Reply
2
Views
5 Years
Discussion Span
Last Post by Cap'nKirk
0

Hi,

just started today with trying to implement a Thread in my application and have come across a problem that I can't seem to figure out.

The application asks the user to enter their userid into a TextBox on the main form which is used to download a specific XML file after they click a button.

If the user has entered an invalid id then a 400 (Bad Request) exception is generated.

I can catch this exception without any problem but then I wish to return the user to the TextBox on the main form to re-enter their id.
I was using this:-

catch (Exception) // Check to make sure the StoreID that has been entered is actually valid 
                {
                    MessageBox.Show("Your request has returned an error. This can be because of two reasons: \n\ni. You have enetered an invalid Store ID. \n\nii. The Cafe Press API is currently down. \n\nPlease try again. ", "Bad Request", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    StoreIDtb.Text = "";
                    StoreIDtb.Focus();
                    return;   
                }

The problem is that I get another error with this:-


- Thrown: "Cross-thread operation not valid: Control 'StoreIDtb' accessed from a thread other than the thread it was created on." (System.InvalidOperationException) Exception Message = "Cross-thread operation not valid: Control 'StoreIDtb' accessed from a thread other than the thread it was created on.", Exception Type = "System.InvalidOperationException"

Now I can see why this is happening but how can I rectify it?

I have tried in testing to remove anything that caused this 'cross-thread' issue to make the 'catch' block as:-

catch (Exception) // Check to make sure the StoreID that has been entered is actually valid 
                {
                    MessageBox.Show("Your request has returned an error. This can be because of two reasons: \n\ni. You have enetered an invalid Store ID. \n\nii. The Cafe Press API is currently down. \n\nPlease try again. ", "Bad Request", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

but then I get this error:-


+ Thrown: "Object reference not set to an instance of an object." (System.NullReferenceException) Exception Message = "Object reference not set to an instance of an object.", Exception Type = "System.NullReferenceException"


in the 'finally' block which is straight after the 'catch' block

It's hard to know how much of the code to post here, so I'll do my best. Here is the majority of the code in question, if any more is required, please let me know.

private void Download(object startPoint)
        {
                try
                {
                    string DIRpath = Path.Combine(Application.StartupPath, "Raw XML"); // Create a holding folder for the raw XML
                    Directory.CreateDirectory(DIRpath);

                    // Put the object argument into an int variable
                    int startPointInt = Convert.ToInt32(startPoint);
                    // Create a request to the file we are downloading
                    webRequest = (HttpWebRequest)WebRequest.Create("http://open-api.cafepress.com/product.countDeepByStore.cp?v=3&appKey={api-key}&storeId=" + StoreIDtb.Text);
                    // Set the starting point of the request
                    webRequest.AddRange(startPointInt);

                    // Set default authentication for retrieving the file
                    webRequest.Credentials = CredentialCache.DefaultCredentials;
                    // Retrieve the response from the server
                    webResponse = (HttpWebResponse)webRequest.GetResponse();
                    // Ask the server for the file size and store it
                    Int64 fileSize = webResponse.ContentLength;

                    // Open the URL for download 
                    strResponse = webResponse.GetResponseStream();
                    if (startPointInt == 0)
                    {
                    strLocal = new FileStream(DIRpath + "/" + StoreIDtb.Text + "-ItemCount.xml", FileMode.Create, FileAccess.Write, FileShare.None);
                    }
                    // It will store the current number of bytes we retrieved from the server
                    int bytesSize = 0;
                    // A buffer for storing and writing the data retrieved from the server
                    byte[] downBuffer = new byte[2048];

                    // Loop through the buffer until the buffer is empty
                    while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
                    {
                    // Write the data from the buffer to the local hard drive
                    strLocal.Write(downBuffer, 0, bytesSize);
                    // Invoke the method that updates the form's label and progress bar
                    this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { strLocal.Length, fileSize + startPointInt });
                    }
                }
                    catch (Exception) // Check to make sure the StoreID that has been entered is actually valid 
                {
                    MessageBox.Show("Your request has returned an error. This can be because of two reasons: \n\ni. You have enetered an invalid Store ID. \n\nii. The Cafe Press API is currently down. \n\nPlease try again. ", "Bad Request", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    StoreIDtb.Text = "";
                    StoreIDtb.Focus();
                    return;   
                }

            finally
            {
                // When the above code has ended, close the streams
                strResponse.Close();
                strLocal.Close();
            }
        }

Regards..,

MT

I think I have got it sorted now.

I had to use 'Invoke & delegate' for control outside of the current thread and I changed the 'finally' block so the 'nullexception' has been cured.

Code below:-

catch (Exception) // Check to make sure the StoreID that has been entered is actually valid 
                {
                    MessageBox.Show("Your request has returned an error. This can be because of two reasons: \n\ni. You have enetered an invalid Store ID. \n\nii. The Cafe Press API is currently down. \n\nPlease try again. ", "Bad Request", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    if (StoreIDtb.InvokeRequired) { Invoke((MethodInvoker)delegate() { StoreIDtb.Text = ""; }); }
                    if (StoreIDtb.InvokeRequired) { Invoke((MethodInvoker)delegate() { StoreIDtb.Focus(); }); }
                    StatusBarlbl.Text = "Ready...";
                    return;   
                }

            finally
            {
                // When the above code has ended, close the streams
                if (strResponse != null)
                { strResponse.Close(); }
                if (strLocal != null)
                { strLocal.Close(); }
            }

Regards..,

MT

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.