为什么我得到异常:调用的目标抛出了异常?

时间:2012-08-25 02:20:54

标签: c#

我首先使用此代码构造函数和按钮单击事件:

using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using System.IO;
using System.Collections;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        DirectoryInfo dirinf = new DirectoryInfo(@"C:\");
        List<FileSystemInfo> fsi = new List<FileSystemInfo>();

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
            button1.Enabled = false;
        }

然后我有一个搜索功能和一个backgroundowrker DoWork活动:

public void Search(string strExtension,
                            DirectoryInfo di,
                            List<FileSystemInfo> pResult)
        {
            try
            {

                foreach (FileInfo fi in di.GetFiles())
                {
                    if (InvokeRequired)
                    {
                        BeginInvoke(new Action(() => label2.Text = fi.Name));
                    }
                    if (fi.Name == "MessageLog.xsl")
                    {
                        foreach (FileInfo fii in di.GetFiles())
                        {
                        if (fii.Extension == strExtension)
                            pResult.Add(fii);
                        }
                        if (InvokeRequired)
                        {
                            BeginInvoke(new Action(() => textBox1.AppendText("Number Of History Files Found: ===> " + pResult.Count.ToString() + Environment.NewLine)));
                        }

                    }
                }

                    foreach (DirectoryInfo diChild in di.GetDirectories())
                        Search(strExtension, diChild, pResult);

            }
            catch (Exception e)
            {
            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            Search(".xml", dirinf, fsi);
            for (int i = 0; i < fsi.Count; i++)
            {
                if (InvokeRequired)
                {
                    BeginInvoke(new Action(() => textBox1.AppendText(fsi[i - 1].FullName + Environment.NewLine)));
                }

            }
        }

当它进入DoWork活动的部分时:

for (int i = 0; i < fsi.Count; i++)
                {
                    if (InvokeRequired)
                    {
                        BeginInvoke(new Action(() => textBox1.AppendText(fsi[i - 1].FullName + Environment.NewLine)));
                    }

                }

在一行或两次迭代之后,它在Program.cs中抛出异常:

Application.Run(new Form1());

调用目标抛出了异常

通过向backgroundworker完成的事件报告来解决它:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            Search(".xml", dirinf, fsi);
            backgroundWorker1.ReportProgress(100);

        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            for (int i = 0; i < fsi.Count; i++)
            {                
                    textBox1.AppendText(fsi[i].FullName + Environment.NewLine);
            }
        }

工作得很好。

1 个答案:

答案 0 :(得分:2)

您已经解决了问题(正确地说,这应该在Completed事件中完成)。

剩下的是一个解释:

您正在使用Action lambda中的变量i,它是DoWork方法的本地变量。这意味着所有代码都使用1个共享(盒装)版本的变量。它被称为“关闭循环变量”。

症状适合:lambdas执行异步,当第二个或第三个开始执行主循环时已经i == fsi.Count。 (内部)异常应为“索引超出范围”。

for (int i = 0; i < fsi.Count; i++)
{
    if (InvokeRequired)
    {
        BeginInvoke(new Action(() => 
            textBox1.AppendText(fsi[i - 1].FullName   // captured 'i'
            + Environment.NewLine)));
    }
}

可以通过这种方式修复:

for (int i = 0; i < fsi.Count; i++)
{
    if (InvokeRequired)   
    {
        int iCopy = i;     // 1 instance per loop

        BeginInvoke(new Action(() => 
            textBox1.AppendText(fsi[iCopy - 1].FullName  
            + Environment.NewLine)));
    }
}