首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >线程交互(从一个线程到另一个线程的数据) c#

线程交互(从一个线程到另一个线程的数据) c#
EN

Stack Overflow用户
提问于 2012-11-15 03:02:01
回答 2查看 1.8K关注 0票数 1

我需要将信息从扫描数据的线程传递到记录信息线程(写入xml文件)。它应该看起来像这样:

Application.Run() -完整

扫描线程完成

正在写入XLM线程-?

UI更新线程-我想我做到了

我现在得到的是:

代码语言:javascript
复制
        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线程?

EN

Stack Overflow用户

回答已采纳

发布于 2012-11-15 04:04:18

下面是一个线程如何生成另一个线程使用的数据的通用机制。无论您使用哪种方法(即:现成的类),内部原则都保持不变。主要的参与者是(请注意,在System.Threading命名空间中有许多可用的锁定类,但这些类最适合此场景:

AutoResetEvent -这允许线程进入睡眠模式(不消耗资源),直到另一个线程将其唤醒。“自动”部分意味着一旦线程唤醒,类就会被重置,因此下一次Wait()调用将再次将其置于休眠状态,而无需重置任何内容。

ReaderWriterLockReaderWriterLockSlim (如果您使用的是.NET 4,建议使用第二个线程)-这只允许一个线程锁定写入数据,但多个线程可以读取数据。在这种特殊情况下,只有一个读取线程,但如果有多个读取线程,方法也不会有什么不同。

代码语言:javascript
复制
// 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,而使用一个并发安全的集合,比如ConcurrentQueue,它将在内部确保读/写是线程安全的。不过,AutoResetEvent仍然是必需的。

.NET 4提供了一种机制,可以用来避免甚至AutoResetEvent - BlockingCollection的需要-这个类为线程提供了休眠直到数据可用的方法。MSDN page包含有关如何使用它的示例代码。

票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13385509

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档