Doron Muzar
Doron Muzar

Reputation: 443

Why I'm getting exception: InvalidOperationException?

The exception is on the code:

private void DownloadProgressCallback(object sender, DownloadProgressChangedEventArgs e)
{
   ActiveDownloadJob adJob = e.UserState as ActiveDownloadJob;
   if (adJob != null && adJob.ProgressBar != null)
   {
      adJob.ProgressBar.Invoke((Action)(() => adJob.ProgressBar.Value = e.ProgressPercentage));
   }
}

On the line:

adJob.ProgressBar.Invoke((Action)(() => adJob.ProgressBar.Value = e.ProgressPercentage));

This is the ActiveDownloadJob class in form1:

class ActiveDownloadJob
{
            public DownloadImages.DownloadData DownloadData;
            public ProgressBar ProgressBar;
            public WebClient WebClient;

            public ActiveDownloadJob(DownloadImages.DownloadData downloadData, ProgressBar progressBar, WebClient webClient)
            {
                try
                {
                    this.DownloadData = downloadData;
                    this.ProgressBar = progressBar;
                    this.WebClient = webClient;
                }
                catch (Exception err)
                {
                    MessageBox.Show(err.ToString());
                }
            }
        }

Im not sure i need to invoke this line since im not using now a backgroundworker , but im not sure.

This is the full exception message: Invoke or BeginInvoke cannot be called on a control until the window handle has been created

System.InvalidOperationException was unhandled by user code
  HResult=-2146233079
  Message=Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
       at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
       at System.Windows.Forms.Control.Invoke(Delegate method)
       at WeatherMaps.Form1.DownloadProgressCallback(Object sender, DownloadProgressChangedEventArgs e) in d:\C-Sharp\WeatherMaps\WeatherMaps\WeatherMaps\Form1.cs:line 290
       at System.Net.WebClient.OnDownloadProgressChanged(DownloadProgressChangedEventArgs e)
       at System.Net.WebClient.ReportDownloadProgressChanged(Object arg)
  InnerException: 

How can i change this line to be without using Invoke or if Invoke is needed how can i fix the line and the exception ?

I know i should handle it in the Form1 Form closing event but how ? What should i do in the form1 form closing event ?

Upvotes: 4

Views: 6933

Answers (3)

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73442

Yes, you get an exception because Invoke needs to post the "Message" to "Message loop" but Handle has not been created.

Use InvokeRequired to see whether you need an Invoke, this will return false when Handle is not created yet so invoke it directly.

var method = (Action)(() => adJob.ProgressBar.Value = e.ProgressPercentage);
if(adJob.ProgressBar.InvokeRequired)
    adJob.ProgressBar.Invoke(method);
else
    method();

Upvotes: 5

Mike Perrenoud
Mike Perrenoud

Reputation: 67898

The issue is you're trying to modify the progress bar before it has a Window Handle. One way to solve it would be:

if (adJob.ProgressBar.Handle != IntPtr.Zero)
{
    adJob.ProgressBar.Invoke((Action)(() =>
        adJob.ProgressBar.Value = e.ProgressPercentage));
}

This is likely caused by the fact that you're invoking this method before the Form is actually shown.

Upvotes: 3

a.malyushko
a.malyushko

Reputation: 83

Try it:

MethodInvoker mi = () => adJob.ProgressBar.Value = e.ProgressPercentage;
if(InvokeRequired) BeginInvoke(mi);
else mi();

Upvotes: -1

Related Questions