2012-11-14 122 views
1

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

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线程?

+1

什么是你的问题? –

+0

http://stackoverflow.com/questions/334860/in-c-sharp-what-is-the-recommended-way-of-passing-data-between-2-threads –

+1

看看生产者消费者。 http://msdn.microsoft.com/en-us/library/dd267312.aspx http://msdn.microsoft.com/en-us/library/dd267312.aspx – Paparazzi

回答

1

这是一个通用机制,它是一个线程如何生成另一个线程所消耗的数据。无论采用什么方法(阅读:现成的课程),您都会使用内部原则保持不变。主要球员(注意,在System.Threading命名空间中可用的许多锁类,可以使用,但这些是最适合这样的场景:

AutoResetEvent - 这允许一个线程进入睡眠模式(不消耗资源)直到另一个线程将它唤醒为止,'auto'部分意味着一旦线程唤醒,该类将被重置,以便下一个Wait()调用再次将其置于睡眠状态,而不需要重置任何东西。 ReaderWriterLockSlim(如果您使用的是.NET 4,建议使用第二个) - 这允许只有一个线程锁定写入数据,但多个线程可以读取数据。在这种情况下,只有一个阅读线程,但如果有很多,这种方法不会有所不同。

// 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包含有关如何使用它的示例代码。

相关问题