1

スキャンデータのスレッドから記録情報スレッド(xmlファイルへの書き込み)に情報を渡す必要があります。次のようになります。

Application.Run() - 完了

スレッドのスキャン - 完了

xlm スレッドへの書き込み - ???

UI 更新スレッド - 実行したと思います

そして、私が今得たもの:

        private void StartButtonClick(object sender, EventArgs e)
    {
        if (FolderPathTextBox.Text == String.Empty || !Directory.Exists(FolderPathTextBox.Text)) return;
        {
            var nodeDrive = new TreeNode(FolderPathTextBox.Text);
            FolderCatalogTreeView.Nodes.Add(nodeDrive);
            nodeDrive.Expand();
            var t1 = new Thread(() => AddDirectories(nodeDrive));
            t1.Start();
        }
    }

     private void AddDirectories(TreeNode node)
    {
        string strPath = node.FullPath;
        var dirInfo = new DirectoryInfo(strPath);
        DirectoryInfo[] arrayDirInfo;
        FileInfo[] arrayFileInfo;

        try
        {
            arrayDirInfo = dirInfo.GetDirectories();
            arrayFileInfo = dirInfo.GetFiles();
        }
        catch
        {

            return;
        }

      //Write data to xml file
        foreach (FileInfo fileInfo in arrayFileInfo)
        {
            WriteXmlFolders(null, fileInfo);
        }
        foreach (DirectoryInfo directoryInfo in arrayDirInfo)
        {
            WriteXmlFolders(directoryInfo, null);
        }


        foreach (TreeNode nodeFil in arrayFileInfo.Select(file => new TreeNode(file.Name)))
        {
            FolderCatalogTreeView.Invoke(new ThreadStart(delegate { node.Nodes.Add(nodeFil); }));
        }

        foreach (TreeNode nodeDir in arrayDirInfo.Select(dir => new TreeNode(dir.Name)))
        {
            FolderCatalogTreeView.Invoke(new ThreadStart(delegate
                {node.Nodes.Add(nodeDir);
                }));

            StatusLabel.BeginInvoke(new MethodInvoker(delegate
                {
     //UI update...some code here
                }));
            AddDirectories(nodeDir);
        }
    }

      private void WriteXmlFolders(DirectoryInfo dir, FileInfo file)
    {//writing information into the file...some code here}

AddDirectories(再帰メソッド)スレッドからWriteXmlFoldersスレッドにデータを渡す方法は?

4

2 に答える 2

1

これは、あるスレッドが別のスレッドが消費するデータを生成する一般的なメカニズムです。どのようなアプローチ(既成のクラスを読む)に関係なく、内部原則を使用することは同じままです。主なプレーヤーは次のとおりです(名前空間で使用できる多くのロッククラスがありますSystem.Threadingが、これらはこのシナリオに最も適しています。

AutoResetEvent-これにより、別のスレッドがウェイクアップするまで、スレッドを(リソースを消費せずに)スリープモードにすることができます。'auto'の部分は、スレッドがウェイクアップするとクラスがリセットされるため、次のWait()呼び出しでスレッドを再びスリープ状態にすることを意味します。何もリセットする必要はありません。

ReaderWriterLockまたはReaderWriterLockSlim(.NET 4を使用している場合は、2番目を使用することをお勧めします)-これにより、1つのスレッドだけがデータの書き込みをロックできますが、複数のスレッドがデータを読み取ることができます。この特定のケースでは、読み取りスレッドは1つだけですが、多くの場合、アプローチに違いはありません。

// The mechanism for waking up the second thread once data is available
AutoResetEvent _dataAvailable = new AutoResetEvent();

// The mechanism for making sure that the data object is not overwritten while it is being read.
ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim();

// The object that contains the data (note that you might use a collection or something similar but anything works
object _data = null;

void FirstThread()
{
    while (true)
    {
        // do something to calculate the data, but do not store it in _data

        // create a lock so that the _data field can be safely updated.
        _readWriteLock.EnterWriteLock();
        try
        {
            // assign the data (add into the collection etc.)
            _data = ...;

            // notify the other thread that data is available
            _dataAvailable.Set();
        }
        finally
        {
            // release the lock on data
            _readWriteLock.ExitWriteLock();
        }
    }
}

void SecondThread()
{
    while (true)
    {
        object local; // this will hold the data received from the other thread

        // wait for the other thread to provide data
        _dataAvailable.Wait();

        // create a lock so that the _data field can be safely read
        _readWriteLock.EnterReadLock();
        try
        {
            // read the data (add into the collection etc.)
            local = _data.Read();
        }
        finally
        {
            // release the lock on data
            _readWriteLock.ExitReadLock();
        }

        // now do something with the data
    }
}

.NET 4では、読み取り/書き込みがスレッドセーフであることを内部的に確認するReadWriteLockような、同時実行に対して安全なコレクションの1つを使用および使用することを回避できます。ConcurrentQueueしかし、それAutoResetEventはまだ必要です。

AutoResetEvent.NET 4は、偶数の必要性を回避するために使用できるメカニズムを提供します---BlockingCollectionこのクラスは、データが利用可能になるまでスレッドがスリープするためのメソッドを提供します。MSDNページには、その使用方法に関するサンプルコードが含まれています。

于 2012-11-14T20:04:18.123 に答える
1

答えとして使う場合

生産者/消費者を見てみましょう。

BlockingCollectionクラス

方法:さまざまな生産者/消費者パターンを実装する

于 2012-11-14T20:52:20.583 に答える