Reputation: 443
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
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
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
Reputation: 83
Try it:
MethodInvoker mi = () => adJob.ProgressBar.Value = e.ProgressPercentage;
if(InvokeRequired) BeginInvoke(mi);
else mi();
Upvotes: -1