1

私はこのコードを最初にコンストラクターとボタンクリックイベントにしています:

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

                }

1 回または 2 回の繰り返しの後、次の行の Program.cs で例外がスローされます。

Application.Run(new Form1());

呼び出しのターゲットによって例外がスローされました

バックグラウンドワーカーの完了イベントに報告することで解決しました:

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

ちょうどよく働いています。

4

1 に答える 1

2

あなたはすでに問題を解決しています (正しく、これは Completed イベントで行う必要があります)。

残っているのは説明です:

iActionラムダ内で、DoWorkメソッドにローカルな変数を使用しています。これは、すべてのコードが 1 つの共有 (ボックス化) バージョンの変数を使用することを意味します。これは「ループ var を閉じる」と呼ばれます。

症状は次のとおりです。ラムダは非同期で実行され、2番目または3番目がメインループの実行を開始すると、すでに作成されてい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)));
    }
}
于 2012-08-25T05:39:22.247 に答える