为什么我得到异常:InvalidOperationException?

时间:2013-11-13 15:43:52

标签: c# winforms invoke

例外是代码:

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));
   }
}

在线:

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

这是form1中的ActiveDownloadJob类:

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());
                }
            }
        }

我不确定我是否需要调用此行,因为我现在不使用背景工作者,但我不确定。

这是完整的异常消息:在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke

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: 

如何在不使用Invoke的情况下更改此行,或者如果需要Invoke,我该如何修复该行和异常?

我知道我应该在Form1 Form结束活动中处理它,但是如何处理?我应该在form1表格结束活动中做些什么?

3 个答案:

答案 0 :(得分:5)

是的,您收到异常,因为Invoke需要将“消息”发布到“消息循环”,但尚未创建Handle

使用InvokeRequired查看是否需要Invoke,当尚未创建Handle时,这将返回false,因此直接调用它。

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

答案 1 :(得分:3)

问题是您正在尝试在具有窗口句柄之前修改进度条。解决问题的一种方法是:

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

这可能是因为您在实际显示Form之前调用此方法。

答案 2 :(得分:-1)

试一试:

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