• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 340
  • Last Modified:

Code is dying trying to access the main UI thread

In my code below, it is dying trying to access the main UI thread.  There is a background worker that is checking to see if there is a new version of the program, but if it has not completed, could that cause the problem?

 
public int uploadAmazonFiles(string[] args) {

            //  instantiate implementation of MWS
            MarketplaceWebServiceConfig config = new MarketplaceWebServiceConfig();
            if (cbUploadAmazon.Checked)
                config.ServiceURL = @"https://mws.amazonservices.com";
            else if (cbUploadAmazonUK.Checked)
                config.ServiceURL = @"https://mws.amazonservices.co.uk";

            const string applicationName = "Prager Inventory Manager";
            const string applicationVersion = "11.5.0";

            MarketplaceWebServiceClient service = new MarketplaceWebServiceClient(
                "AKIA**********YTRSDA",  //  developer access key
                "37eqs33ahd+Vbrc2AR/***************5J8h0G", //  developer secret key
                applicationName,
           applicationVersion, config);

            SubmitFeedRequest request = new SubmitFeedRequest();
            request.Merchant = tbMerchantID.Text;  //  user's merchant id
            request.MarketplaceIdList = new IdList();
            request.MarketplaceIdList.Id = new List<string>(new string[] { tbMarketplaceID.Text });  //  user's marketplace id

            request.FeedContent = File.Open(args[2], FileMode.Open, FileAccess.Read);
            request.ContentMD5 = MarketplaceWebServiceClient.CalculateContentMD5(request.FeedContent);
            request.FeedContent.Position = 0;  //  Calculating the MD5 hash value exhausts the stream; therefore we have to reset the position
            request.FeedType = "_POST_FLAT_FILE_BOOKLOADER_DATA_";
            if (cbUploadPurgeReplace.Checked)
                request.PurgeAndReplace = true;
            else
                request.PurgeAndReplace = false;

            try {
                SubmitFeedResponse response = service.SubmitFeed(request);  //  submit the feed... (<----- IT DIES HERE)

                if (response.IsSetSubmitFeedResult()) {
                    SubmitFeedResult submitFeedResult = response.SubmitFeedResult;
                    if (submitFeedResult.IsSetFeedSubmissionInfo()) {
                        FeedSubmissionInfo feedSubmissionInfo = submitFeedResult.FeedSubmissionInfo;
                        if (feedSubmissionInfo.IsSetFeedSubmissionId()) {
                            lbUploadStatus.Items.Insert(0, "-->SubmissionID: " + feedSubmissionInfo.FeedSubmissionId);
                            Clipboard.SetText(feedSubmissionInfo.FeedSubmissionId);  //  copy it to the clipboard also 11.5.0
                        }
                    }
                }

            }
            catch (MarketplaceWebServiceException ex) {

                MessageBox.Show("MWS Exception: " + ex.Message + "\nResponse Status: " + ex.StatusCode +
                    "\nError Code: " + ex.ErrorCode + "\nError Type: " + ex.ErrorType + "\nRequest ID: " + ex.RequestId,
                    "Prager, Software", MessageBoxButtons.OK, MessageBoxIcon.Error);

                throw new System.ArgumentException("MWS Exception");
            }

            return 0;
        }

Open in new window


This is the stack:
 
at Prager_Book_Inventory.mainForm.ShowThreadExceptionDialog(String title, Exception ex, String mtv) in D:\Prager Software\Inventory\Prager Book Maintenance\Main Form.cs:line 3189
at Prager_Book_Inventory.mainForm.Form1_UIThreadException(Object sender, ThreadExceptionEventArgs t) in D:\Prager Software\Inventory\Prager Book Maintenance\Main Form.cs:line 3106
at System.Windows.Forms.Application.ThreadContext.OnThreadException(Exception t)
at System.Windows.Forms.Control.WndProcException(Exception e)
at System.Windows.Forms.Control.ControlNativeWindow.OnThreadException(Exception e)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.Control.SendMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.Control.ReflectMessageInternal(IntPtr hWnd, Message& m)
at System.Windows.Forms.Control.WmCommand(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Open in new window

0
rmmarsh
Asked:
rmmarsh
  • 5
  • 4
1 Solution
 
strickddCommented:
To perform a thread safe call to the UI thread, you need to pass in a delegate function to the thread.

http://msdn.microsoft.com/en-us/library/ms173171%28v=vs.80%29.aspx
0
 
rmmarshAuthor Commented:
Which thread would that be?  the Amazon call or the one to get version information, or both?
0
 
strickddCommented:
Any time you spawn a new thread and need to access another thread, you need to either use delegates or InvokeRequired methods. Delegates are easier in my opinion because they work for all cases whereas the Invoke option is mostly restricted to GUI Control access.
0
Get your Disaster Recovery as a Service basics

Disaster Recovery as a Service is one go-to solution that revolutionizes DR planning. Implementing DRaaS could be an efficient process, easily accessible to non-DR experts. Learn about monitoring, testing, executing failovers and failbacks to ensure a "healthy" DR environment.

 
rmmarshAuthor Commented:
So should I get rid of the "background worker" and do it another way using Delegates?  I see where the backgroundWorker.DoWork is indeed altering an object in the main thread!
0
 
strickddCommented:
You can use the background worker just fine, but you either have to use the delegate or invoke option to change objects on the main thread. You can also wait until the background worker completes which will re-join the main thread.
0
 
rmmarshAuthor Commented:
You can also wait until the background worker completes which will re-join the main thread.

You mean wait until it completes, then modify the main UI object? (which is a toolStripMenuItem.text.  I did it that way because that was the only way I knew of to get it on the menu bar).  I found a great example of this, so I'm just checking to make sure I'm on the right track.

private void backgroundWorkeer1_RunWorkerCompleted (object sender, RunWorkerCompleted EventsArgs e)
{
this.toolStripMenuItem.Text = "There is a new version available";
}

Open in new window

0
 
strickddCommented:
That will do it. If you need, you can re-invoke the background worker again from here.
0
 
rmmarshAuthor Commented:
OK this is what I have, but it's not giving me what I expected... I get to the RunWorkerCompleted, but don't see a way to get access to the data returned from DownloadVersionInfo.

        //-------------------    background worker to check for program updates    ---------------|
        private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {
            //m = Regex.Match(versionNumber, "BETA");
            //if (m.Success)  //  if we are in BETA, don't check for version
            //    return;

            string replyFromHost = DownloadVersionInfo();
            string[] workingVerNbr = versionNumber.Split(' ');
            //replyFromHost = ">10.2.0:Critical<\n";  //  testing only!  <----------------
            //replyFromHost = ">4.5c<\n";  //  testing only!  <----------------

            string reply = "";
            if (replyFromHost.Length > 1)
                reply = replyFromHost.Substring(1, replyFromHost.IndexOf('<') - 1);

            if (reply.Length >= 3)  //  make sure we got a good reply
            {
                if (reply != workingVerNbr[0]) {
                    if (replyFromHost.Contains("Critical")) {
                        newVersionAvailableToolStripMenuItem.Text = "There is a CRITICAL update available for this program!";
                        newVersionAvailableToolStripMenuItem.Visible = true;
                    }
                    else {
                        newVersionAvailableToolStripMenuItem.Visible = true;
                     }
                }
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
          
        }

Open in new window

0
 
rmmarshAuthor Commented:
I figured it out... thank you so much for your time... I really appreciate it!
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now