为什么有时我在Backgroundworker中遇到异常做工作事件InvalidOperationException?

时间:2014-08-23 08:42:47

标签: c# .net winforms

在form1构造函数中我正在做:

buttonSnap.Enabled = false;
backgroundWorker1.RunWorkerAsync();

然后我点击一下按钮:

private void buttonSnap_Click(object sender, EventArgs e)
        {
            ClearGraphics = true;
            this.listBoxSnap.Items.Clear();
            this.pictureBoxSnap.Image = null;
            backgroundWorker1.RunWorkerAsync();
            buttonSnap.Enabled = false;
        }

在后台工作人员做事件中我添加了一个listBox项目,每个项目都是一个捕获的窗口:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                if (this.IsHandleCreated)
                {
                    listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.Add("Minimized Windows"); }));
                    listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true, true).ToArray()); }));
                }
            }
            catch (Exception ee)
            {
                string t = "exception " + ee.ToString();
            }
        }

这是WindowSnap.cs类的链接:

WindowSnap.cs

这是WindowSnapCollection.cs的链接:

WindowSnapCollection.cs

在WindowSnap.cs中有方法GetallWindows:

public static WindowSnapCollection GetAllWindows(bool minimized, bool specialCapturring)
        {
            windowSnaps = new WindowSnapCollection();
            countMinimizedWindows = minimized;//set minimized flag capture
            useSpecialCapturing = specialCapturring;//set specialcapturing flag
            EnumWindowsCallbackHandler callback = new EnumWindowsCallbackHandler(EnumWindowsCallback);
            EnumWindows(callback, IntPtr.Zero);
            return new WindowSnapCollection(windowSnaps.ToArray(), true);
        }

现在有时会在该行的DoWork事件中抛出异常:

listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true, true).ToArray()); }));

例外是:

在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke

完整的异常消息:

System.InvalidOperationException was caught
  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 MinimizeCapture.Form1.backgroundWorker1_DoWork(Object sender, DoWorkEventArgs e) in c:\Temp\Capture\Form1.cs:line 81
  InnerException: 

第81行是:

listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.Add("Minimized Windows"); }));

现在我在backgroundworker中添加了工作事件尝试并捕获,有时它停在字符串t ...在catch中。然后我补充说:

if(this.IsHandleCreated)

所以现在有时它会遇到同样的问题,但不会停止捕获并抛出异常。 同样的问题仍然存在,有时它会解决异常描述的问题。

这:if(this.IsHandleCreated)没有解决它。

1 个答案:

答案 0 :(得分:0)

您正在检查this.InHandleCreated,它返回是否为当前实例创建句柄。我认为这是一个表格。但是,立即致电listBoxSnap.Invoke即可解决问题。此时可能尚未创建listBoxSnap的句柄。您需要改为使用listBoxSnap.InHandleCreated

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {
        if (listBoxSnap.IsHandleCreated)
        {
            listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.Add("Minimized Windows"); }));
            listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true, true).ToArray()); }));
        }
    }
    catch (Exception ee)
    {
        string t = "exception " + ee.ToString();
    }
}

此外,如果这是您的真实代码,则根本不需要BackgroundWorker。你没有使用工作线程。所有工作仅由主线程完成。

我建议您执行与您的代码实际相同的以下操作(因为您的DoWork没有任何用处)。

buttonSnap.Enabled = false;
this.listBoxSnap.Items.Add("Minimized Windows"); }));
this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true, true).ToArray());